Files
2025-06-09 23:23:13 +08:00

1 line
7.8 MiB

{"MonoBehaviour":{"m_Enabled":true,"m_EditorHideFlags":0,"m_Name":"","m_EditorClassIdentifier":"","entries":[{"srpTarget":0,"UnityVersionMin":20212,"UnityVersionMax":30000,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: Standard\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n }\n SubShader\n {\n Tags { \"RenderType\" = \"Opaque\" \"Queue\" = \"Geometry\" }\n\n \n \n Pass\n {\n\t\t Name \"FORWARD\"\n\t\t Tags { \"LightMode\" = \"ForwardBase\" }\n \n \n\n CGPROGRAM\n // compile directives\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n #pragma multi_compile_instancing\n #pragma multi_compile_fog\n #pragma multi_compile_fwdbase\n #include \"HLSLSupport.cginc\"\n #define UNITY_INSTANCED_LOD_FADE\n #define UNITY_INSTANCED_SH\n #define UNITY_INSTANCED_LIGHTMAPSTS\n\n #include \"UnityShaderVariables.cginc\"\n #include \"UnityShaderUtilities.cginc\"\n // -------- variant for: <when no other keywords are defined>\n\n #include \"UnityCG.cginc\"\n #include \"Lighting.cginc\"\n #include \"UnityPBSLighting.cginc\"\n #include \"AutoLight.cginc\"\n #define SHADER_PASS SHADERPASS_FORWARD\n #define _PASSFORWARD 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _STANDARD 1\n// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same\n// texturing library they use. However, since they are not included in the standard pipeline by default, there is no\n// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without\n// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead\n// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not\n// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.\n\n#if defined(SHADER_API_GAMECORE)\n\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\t#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r\n\t#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_XBOXONE)\n\t\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_PSSL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n\n#elif defined(SHADER_API_D3D11)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_METAL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_VULKAN)\n// This file assume SHADER_API_VULKAN is defined\n\t// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.\n\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_SWITCH)\n\t// This file assume SHADER_API_SWITCH is defined\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_GLCORE)\n\n\t// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 46)\n\t#define OPENGL4_1_SM5 1\n\t#else\n\t#define OPENGL4_1_SM5 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\n\t#if OPENGL4_1_SM5\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#endif\n\n\n\t#elif defined(SHADER_API_GLES3)\n\n\t// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 40)\n\t#define GLES3_1_AEP 1\n\t#else\n\t#define GLES3_1_AEP 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#if GLES3_1_AEP\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\t#else\n\t#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\t#endif\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#if GLES3_1_AEP\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\t#endif\n\n\n#elif defined(SHADER_API_GLES)\n\n\n\t#define uint int\n\n\t#define rcp(x) 1.0 / (x)\n\t#define ddx_fine ddx\n\t#define ddy_fine ddy\n\t#define asfloat\n\t#define asuint(x) asint(x)\n\t#define f32tof16\n\t#define f16tof32\n\n\t#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray\n\t#define TEXTURECUBE(textureName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray\n\t#define TEXTURE3D(textureName) sampler3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) sampler2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_HALF(textureName) sampler3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\t#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\n\t#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\n\t#define SAMPLER(samplerName)\n\t#define SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)\n\n\t#if (SHADER_TARGET >= 30)\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))\n\t#else\n\t // No lod support. Very poor approximation with bias.\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)\n\t#endif\n\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)\n\t// No lod support. Very poor approximation with bias.\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)\n\n\n\t// Not supported. Can't define as error because shader library is calling these functions.\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)\n\n\t// Gather not supported. Fallback to regular texture sampling.\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\n#else\n#error unsupported shader api\n#endif\n\n\n\n\n// default flow control attributes\n#ifndef UNITY_BRANCH\n# define UNITY_BRANCH\n#endif\n#ifndef UNITY_FLATTEN\n# define UNITY_FLATTEN\n#endif\n#ifndef UNITY_UNROLL\n# define UNITY_UNROLL\n#endif\n#ifndef UNITY_UNROLLX\n# define UNITY_UNROLLX(_x)\n#endif\n#ifndef UNITY_LOOP\n# define UNITY_LOOP\n#endif\n\n\n\n#define _USINGTEXCOORD1 1\n\n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n UNITY_POSITION(pos);\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n float4 lmap : TEXCOORD8;\n #if UNITY_SHOULD_SAMPLE_SH\n half3 sh : TEXCOORD9; // SH\n #endif\n #ifdef LIGHTMAP_ON\n UNITY_LIGHTING_COORDS(10,11)\n UNITY_FOG_COORDS(12)\n #else\n UNITY_FOG_COORDS(10)\n UNITY_SHADOW_COORDS(11)\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef UNITY_MATRIX_I_M\n\n #define UNITY_MATRIX_I_M unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)UNITY_MATRIX_V, norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\tfixed3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n UNITY_SETUP_INSTANCE_ID(v);\n VertexToPixel o;\n UNITY_INITIALIZE_OUTPUT(VertexToPixel,o);\n UNITY_TRANSFER_INSTANCE_ID(v,o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.pos = UnityObjectToClipPos(v.vertex);\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos);\n #endif\n\n o.worldPos = mul(GetObjectToWorldMatrix(), v.vertex).xyz;\n o.worldNormal = UnityObjectToWorldNormal(v.normal);\n o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n\n #ifdef DYNAMICLIGHTMAP_ON\n o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #ifdef LIGHTMAP_ON\n o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n #endif\n\n // SH/ambient and vertex lights\n #ifndef LIGHTMAP_ON\n #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL\n o.sh = 0;\n // Approximated illumination from non-important point lights\n #ifdef VERTEXLIGHT_ON\n o.sh += Shade4PointLights (\n unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,\n unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,\n unity_4LightAtten0, o.worldPos, o.worldNormal);\n #endif\n o.sh = ShadeSHPerVertex (o.worldNormal, o.sh);\n #endif\n #endif // !LIGHTMAP_ON\n\n UNITY_TRANSFER_LIGHTING(o,v.texcoord1.xy); // pass shadow and, possibly, light cookie coordinates to pixel shader\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_TRANSFER_FOG_COMBINED_WITH_TSPACE(o,o.pos); // pass fog coordinates to pixel shader\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o,o.pos); // pass fog coordinates to pixel shader\n #else\n UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader\n #endif\n\n return o;\n }\n\n \n\n // fragment shader\n fixed4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n // prepare and unpack data\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_EXTRACT_FOG_FROM_TSPACE(IN);\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_EXTRACT_FOG_FROM_WORLD_POS(IN);\n #else\n UNITY_EXTRACT_FOG(IN);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n \n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n \n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n\n #ifndef USING_DIRECTIONAL_LIGHT\n fixed3 lightDir = normalize(UnityWorldSpaceLightDir(d.worldSpacePosition));\n #else\n fixed3 lightDir = _WorldSpaceLightPos0.xyz;\n #endif\n float3 worldViewDir = normalize(UnityWorldSpaceViewDir(d.worldSpacePosition));\n\n // compute lighting & shadowing factor\n UNITY_LIGHT_ATTENUATION(atten, IN, d.worldSpacePosition)\n\n #if _USESPECULAR || _USESPECULARWORKFLOW || _SPECULARFROMMETALLIC\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandardSpecular o = (SurfaceOutputStandardSpecular)0;\n #else\n SurfaceOutputStandardSpecular o;\n #endif\n o.Specular = l.Specular;\n o.Occlusion = l.Occlusion;\n o.Smoothness = l.Smoothness;\n #elif _BDRFLAMBERT || _BDRF3 || _SIMPLELIT\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutput o = (SurfaceOutput)0;\n #else\n SurfaceOutput o;\n #endif\n\n o.Specular = l.Specular;\n o.Gloss = l.Smoothness;\n _SpecColor.rgb = l.Specular; // fucking hell Unity, wtf..\n #else\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandard o = (SurfaceOutputStandard)0;\n #else\n SurfaceOutputStandard o;\n #endif\n o.Smoothness = l.Smoothness;\n o.Metallic = l.Metallic;\n o.Occlusion = l.Occlusion;\n #endif\n\n o.Albedo = l.Albedo;\n o.Emission = l.Emission;\n o.Alpha = l.Alpha;\n #if _WORLDSPACENORMAL\n o.Normal = l.Normal;\n #else\n o.Normal = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n fixed4 c = 0;\n // Setup lighting environment\n UnityGI gi;\n UNITY_INITIALIZE_OUTPUT(UnityGI, gi);\n gi.indirect.diffuse = 0;\n gi.indirect.specular = 0;\n gi.light.color = _LightColor0.rgb;\n gi.light.dir = lightDir;\n // Call GI (lightmaps/SH/reflections) lighting function\n UnityGIInput giInput;\n UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);\n giInput.light = gi.light;\n giInput.worldPos = d.worldSpacePosition;\n giInput.worldViewDir = worldViewDir;\n giInput.atten = atten;\n #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)\n giInput.lightmapUV = IN.lmap;\n #else\n giInput.lightmapUV = 0.0;\n #endif\n #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL\n giInput.ambient = IN.sh;\n #else\n giInput.ambient.rgb = 0.0;\n #endif\n giInput.probeHDR[0] = unity_SpecCube0_HDR;\n giInput.probeHDR[1] = unity_SpecCube1_HDR;\n #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)\n giInput.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending\n #endif\n #ifdef UNITY_SPECCUBE_BOX_PROJECTION\n giInput.boxMax[0] = unity_SpecCube0_BoxMax;\n giInput.probePosition[0] = unity_SpecCube0_ProbePosition;\n giInput.boxMax[1] = unity_SpecCube1_BoxMax;\n giInput.boxMin[1] = unity_SpecCube1_BoxMin;\n giInput.probePosition[1] = unity_SpecCube1_ProbePosition;\n #endif\n\n \n\n #if defined(_OVERRIDE_SHADOWMASK)\n float4 mulColor = saturate(dot(l.ShadowMask, unity_OcclusionMaskSelector));\n gi.light.color *= mulColor;\n giInput.light.color *= mulColor;\n #endif\n\n #if _UNLIT\n c.rgb = l.Albedo;\n c.a = l.Alpha;\n #elif _BDRF3 || _SIMPLELIT\n LightingBlinnPhong_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n c += LightingBlinnPhong (o, d.worldSpaceViewDir, gi);\n #elif _USESPECULAR || _USESPECULARWORKFLOW || _SPECULARFROMMETALLIC\n LightingStandardSpecular_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n c += LightingStandardSpecular (o, d.worldSpaceViewDir, gi);\n #else\n LightingStandard_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n c += LightingStandard (o, d.worldSpaceViewDir, gi);\n #endif\n\n c.rgb += o.Emission;\n\n ChainFinalColorForward(l, d, c);\n\n #if !DISABLEFOG\n UNITY_APPLY_FOG(_unity_fogCoord, c); // apply fog\n #endif\n \n\n return c;\n }\n\n ENDCG\n\n }\n\n\n \n\t // ---- deferred shading pass:\n\t Pass\n {\n\t\t Name \"DEFERRED\"\n\t\t Tags { \"LightMode\" = \"Deferred\" }\n\n \n\n CGPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // compile directives\n #pragma target 3.0\n #pragma multi_compile_instancing\n #pragma exclude_renderers nomrt\n #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2\n #pragma multi_compile_prepassfinal\n #include \"HLSLSupport.cginc\"\n #define UNITY_INSTANCED_LOD_FADE\n #define UNITY_INSTANCED_SH\n #define UNITY_INSTANCED_LIGHTMAPSTS\n #include \"UnityShaderVariables.cginc\"\n #include \"UnityShaderUtilities.cginc\"\n #include \"UnityCG.cginc\"\n #include \"Lighting.cginc\"\n #include \"UnityPBSLighting.cginc\"\n\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _STANDARD 1\n// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same\n// texturing library they use. However, since they are not included in the standard pipeline by default, there is no\n// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without\n// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead\n// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not\n// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.\n\n#if defined(SHADER_API_GAMECORE)\n\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\t#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r\n\t#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_XBOXONE)\n\t\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_PSSL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n\n#elif defined(SHADER_API_D3D11)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_METAL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_VULKAN)\n// This file assume SHADER_API_VULKAN is defined\n\t// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.\n\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_SWITCH)\n\t// This file assume SHADER_API_SWITCH is defined\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_GLCORE)\n\n\t// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 46)\n\t#define OPENGL4_1_SM5 1\n\t#else\n\t#define OPENGL4_1_SM5 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\n\t#if OPENGL4_1_SM5\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#endif\n\n\n\t#elif defined(SHADER_API_GLES3)\n\n\t// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 40)\n\t#define GLES3_1_AEP 1\n\t#else\n\t#define GLES3_1_AEP 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#if GLES3_1_AEP\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\t#else\n\t#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\t#endif\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#if GLES3_1_AEP\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\t#endif\n\n\n#elif defined(SHADER_API_GLES)\n\n\n\t#define uint int\n\n\t#define rcp(x) 1.0 / (x)\n\t#define ddx_fine ddx\n\t#define ddy_fine ddy\n\t#define asfloat\n\t#define asuint(x) asint(x)\n\t#define f32tof16\n\t#define f16tof32\n\n\t#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray\n\t#define TEXTURECUBE(textureName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray\n\t#define TEXTURE3D(textureName) sampler3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) sampler2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_HALF(textureName) sampler3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\t#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\n\t#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\n\t#define SAMPLER(samplerName)\n\t#define SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)\n\n\t#if (SHADER_TARGET >= 30)\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))\n\t#else\n\t // No lod support. Very poor approximation with bias.\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)\n\t#endif\n\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)\n\t// No lod support. Very poor approximation with bias.\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)\n\n\n\t// Not supported. Can't define as error because shader library is calling these functions.\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)\n\n\t// Gather not supported. Fallback to regular texture sampling.\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\n#else\n#error unsupported shader api\n#endif\n\n\n\n\n// default flow control attributes\n#ifndef UNITY_BRANCH\n# define UNITY_BRANCH\n#endif\n#ifndef UNITY_FLATTEN\n# define UNITY_FLATTEN\n#endif\n#ifndef UNITY_UNROLL\n# define UNITY_UNROLL\n#endif\n#ifndef UNITY_UNROLLX\n# define UNITY_UNROLLX(_x)\n#endif\n#ifndef UNITY_LOOP\n# define UNITY_LOOP\n#endif\n\n\n\n#define _USINGTEXCOORD1 1\n\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n UNITY_POSITION(pos); // must be named pos because Unity does stupid macro stuff\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n #ifndef DIRLIGHTMAP_OFF\n float3 viewDir : TEXCOORD8;\n #endif\n float4 lmap : TEXCOORD9;\n #ifndef LIGHTMAP_ON\n #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL\n half3 sh : TEXCOORD10; // SH\n #endif\n #else\n #ifdef DIRLIGHTMAP_OFF\n float4 lmapFadePos : TEXCOORD11;\n #endif\n #endif\n\n \n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD19;\n // #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef UNITY_MATRIX_I_M\n\n #define UNITY_MATRIX_I_M unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)UNITY_MATRIX_V, norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\tfixed3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n UNITY_SETUP_INSTANCE_ID(v);\n VertexToPixel o;\n UNITY_INITIALIZE_OUTPUT(VertexToPixel,o);\n UNITY_TRANSFER_INSTANCE_ID(v,o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.pos = UnityObjectToClipPos(v.vertex);\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos);\n #endif\n\n o.worldPos = mul(GetObjectToWorldMatrix(), v.vertex).xyz;\n o.worldNormal = UnityObjectToWorldNormal(v.normal);\n o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n\n float3 viewDirForLight = UnityWorldSpaceViewDir(o.worldPos);\n #ifndef DIRLIGHTMAP_OFF\n float3 worldBinormal = cross(o.worldNormal, o.worldTangent.xyz);\n o.viewDir.x = dot(viewDirForLight, o.worldTangent.xyz);\n o.viewDir.y = dot(viewDirForLight, worldBinormal);\n o.viewDir.z = dot(viewDirForLight, o.worldNormal);\n #endif\n #ifdef DYNAMICLIGHTMAP_ON\n o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #else\n o.lmap.zw = 0;\n #endif\n #ifdef LIGHTMAP_ON\n o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n #ifdef DIRLIGHTMAP_OFF\n o.lmapFadePos.xyz = (mul(GetObjectToWorldMatrix(), v.vertex).xyz - unity_ShadowFadeCenterAndType.xyz) * unity_ShadowFadeCenterAndType.w;\n o.lmapFadePos.w = (-UnityObjectToViewPos(v.vertex).z) * (1.0 - unity_ShadowFadeCenterAndType.w);\n #endif\n #else\n o.lmap.xy = 0;\n #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL\n o.sh = 0;\n o.sh = ShadeSHPerVertex (o.worldNormal, o.sh);\n #endif\n #endif\n\n return o;\n }\n\n \n\n #ifdef LIGHTMAP_ON\n float4 unity_LightmapFade;\n #endif\n fixed4 unity_Ambient;\n\n \n\n // fragment shader\n void Frag (VertexToPixel IN,\n out half4 outGBuffer0 : SV_Target0,\n out half4 outGBuffer1 : SV_Target1,\n out half4 outGBuffer2 : SV_Target2,\n out half4 outEmission : SV_Target3\n #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n , out half4 outShadowMask : SV_Target4\n #endif\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n // prepare and unpack data\n\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_EXTRACT_FOG_FROM_TSPACE(IN);\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_EXTRACT_FOG_FROM_WORLD_POS(IN);\n #else\n UNITY_EXTRACT_FOG(IN);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n \n\n\n\n #ifndef USING_DIRECTIONAL_LIGHT\n fixed3 lightDir = normalize(UnityWorldSpaceLightDir(d.worldSpacePosition));\n #else\n fixed3 lightDir = _WorldSpaceLightPos0.xyz;\n #endif\n float3 worldViewDir = normalize(UnityWorldSpaceViewDir(d.worldSpacePosition));\n\n #if _USESPECULAR || _USESPECULARWORKFLOW || _SPECULARFROMMETALLIC\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandardSpecular o = (SurfaceOutputStandardSpecular)0;\n #else\n SurfaceOutputStandardSpecular o;\n #endif\n o.Specular = l.Specular;\n o.Occlusion = l.Occlusion;\n o.Smoothness = l.Smoothness;\n #elif _BDRFLAMBERT || _BDRF3 || _SIMPLELIT\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutput o = (SurfaceOutput)0;\n #else\n SurfaceOutput o;\n #endif\n\n o.Specular = l.SpecularPower;\n o.Gloss = l.Smoothness;\n _SpecColor.rgb = l.Specular; // fucking hell Unity, wtf..\n #else\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandard o = (SurfaceOutputStandard)0;\n #else\n SurfaceOutputStandard o;\n #endif\n o.Smoothness = l.Smoothness;\n o.Metallic = l.Metallic;\n o.Occlusion = l.Occlusion;\n #endif\n\n\n \n o.Albedo = l.Albedo;\n o.Emission = l.Emission;\n o.Alpha = l.Alpha;\n\n #if _WORLDSPACENORMAL\n o.Normal = l.Normal;\n #else\n o.Normal = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n\n half atten = 1;\n\n // Setup lighting environment\n UnityGI gi;\n UNITY_INITIALIZE_OUTPUT(UnityGI, gi);\n gi.indirect.diffuse = 0;\n gi.indirect.specular = 0;\n gi.light.color = 0;\n gi.light.dir = half3(0,1,0);\n // Call GI (lightmaps/SH/reflections) lighting function\n UnityGIInput giInput;\n UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);\n giInput.light = gi.light;\n giInput.worldPos = d.worldSpacePosition;\n giInput.worldViewDir = worldViewDir;\n giInput.atten = atten;\n #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)\n giInput.lightmapUV = IN.lmap;\n #else\n giInput.lightmapUV = 0.0;\n #endif\n #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL\n giInput.ambient = IN.sh;\n #else\n giInput.ambient.rgb = 0.0;\n #endif\n giInput.probeHDR[0] = unity_SpecCube0_HDR;\n giInput.probeHDR[1] = unity_SpecCube1_HDR;\n #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)\n giInput.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending\n #endif\n #ifdef UNITY_SPECCUBE_BOX_PROJECTION\n giInput.boxMax[0] = unity_SpecCube0_BoxMax;\n giInput.probePosition[0] = unity_SpecCube0_ProbePosition;\n giInput.boxMax[1] = unity_SpecCube1_BoxMax;\n giInput.boxMin[1] = unity_SpecCube1_BoxMin;\n giInput.probePosition[1] = unity_SpecCube1_ProbePosition;\n #endif\n\n \n\n #if _BDRF3 || _SIMPLELIT\n \n LightingBlinnPhong_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n\n outEmission = LightingBlinnPhong_Deferred(o, worldViewDir, gi, outGBuffer0, outGBuffer1, outGBuffer2);\n #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n outShadowMask = UnityGetRawBakedOcclusions (IN.lmap.xy, d.worldSpacePosition);\n #endif\n #ifndef UNITY_HDR_ON\n outEmission.rgb = exp2(-outEmission.rgb);\n #endif\n #elif _USESPECULAR || _USESPECULARWORKFLOW || _SPECULARFROMMETALLIC\n LightingStandardSpecular_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n // call lighting function to output g-buffer\n outEmission = LightingStandardSpecular_Deferred (o, worldViewDir, gi, outGBuffer0, outGBuffer1, outGBuffer2);\n #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n outShadowMask = UnityGetRawBakedOcclusions (IN.lmap.xy, d.worldSpacePosition);\n #endif\n #ifndef UNITY_HDR_ON\n outEmission.rgb = exp2(-outEmission.rgb);\n #endif\n #else\n LightingStandard_GI(o, giInput, gi);\n #if defined(_OVERRIDE_BAKEDGI)\n gi.indirect.diffuse = l.DiffuseGI;\n gi.indirect.specular = l.SpecularGI;\n #endif\n // call lighting function to output g-buffer\n outEmission = LightingStandard_Deferred (o, worldViewDir, gi, outGBuffer0, outGBuffer1, outGBuffer2);\n #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n outShadowMask = UnityGetRawBakedOcclusions (IN.lmap.xy, d.worldSpacePosition);\n #endif\n #ifndef UNITY_HDR_ON\n outEmission.rgb = exp2(-outEmission.rgb);\n #endif\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK) && defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n float4 mulColor = saturate(dot(l.ShadowMask, unity_OcclusionMaskSelector));\n outShadowMask = mulColor;\n #endif\n \n #if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)\n ChainFinalGBufferStandard(l, d, outGBuffer0, outGBuffer1, outGBuffer2, outEmission, outShadowMask);\n #else\n half4 outShadowMask = 0;\n ChainFinalGBufferStandard(l, d, outGBuffer0, outGBuffer1, outGBuffer2, outEmission, outShadowMask);\n #endif\n\n \n }\n\n\n\n\n ENDCG\n\n }\n\n\n \n\n\t // ---- forward rendering additive lights pass:\n\t Pass\n {\n\t\t Name \"FORWARD\"\n\t\t Tags { \"LightMode\" = \"ForwardAdd\" }\n\t\t ZWrite Off Blend One One\n \n \n\n CGPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // compile directives\n #pragma target 3.0\n #pragma multi_compile_instancing\n #pragma multi_compile_fog\n #pragma skip_variants INSTANCING_ON\n #pragma multi_compile_fwdadd_fullshadows\n #include \"HLSLSupport.cginc\"\n #define UNITY_INSTANCED_LOD_FADE\n #define UNITY_INSTANCED_SH\n #define UNITY_INSTANCED_LIGHTMAPSTS\n #include \"UnityShaderVariables.cginc\"\n #include \"UnityShaderUtilities.cginc\"\n\n\n #include \"UnityCG.cginc\"\n #include \"Lighting.cginc\"\n #include \"UnityPBSLighting.cginc\"\n #include \"AutoLight.cginc\"\n\n \n\n #define _PASSFORWARD 1\n #define _PASSFORWARDADD 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _STANDARD 1\n// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same\n// texturing library they use. However, since they are not included in the standard pipeline by default, there is no\n// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without\n// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead\n// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not\n// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.\n\n#if defined(SHADER_API_GAMECORE)\n\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\t#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r\n\t#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_XBOXONE)\n\t\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_PSSL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n\n#elif defined(SHADER_API_D3D11)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_METAL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_VULKAN)\n// This file assume SHADER_API_VULKAN is defined\n\t// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.\n\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_SWITCH)\n\t// This file assume SHADER_API_SWITCH is defined\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_GLCORE)\n\n\t// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 46)\n\t#define OPENGL4_1_SM5 1\n\t#else\n\t#define OPENGL4_1_SM5 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\n\t#if OPENGL4_1_SM5\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#endif\n\n\n\t#elif defined(SHADER_API_GLES3)\n\n\t// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 40)\n\t#define GLES3_1_AEP 1\n\t#else\n\t#define GLES3_1_AEP 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#if GLES3_1_AEP\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\t#else\n\t#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\t#endif\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#if GLES3_1_AEP\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\t#endif\n\n\n#elif defined(SHADER_API_GLES)\n\n\n\t#define uint int\n\n\t#define rcp(x) 1.0 / (x)\n\t#define ddx_fine ddx\n\t#define ddy_fine ddy\n\t#define asfloat\n\t#define asuint(x) asint(x)\n\t#define f32tof16\n\t#define f16tof32\n\n\t#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray\n\t#define TEXTURECUBE(textureName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray\n\t#define TEXTURE3D(textureName) sampler3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) sampler2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_HALF(textureName) sampler3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\t#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\n\t#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\n\t#define SAMPLER(samplerName)\n\t#define SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)\n\n\t#if (SHADER_TARGET >= 30)\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))\n\t#else\n\t // No lod support. Very poor approximation with bias.\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)\n\t#endif\n\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)\n\t// No lod support. Very poor approximation with bias.\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)\n\n\n\t// Not supported. Can't define as error because shader library is calling these functions.\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)\n\n\t// Gather not supported. Fallback to regular texture sampling.\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\n#else\n#error unsupported shader api\n#endif\n\n\n\n\n// default flow control attributes\n#ifndef UNITY_BRANCH\n# define UNITY_BRANCH\n#endif\n#ifndef UNITY_FLATTEN\n# define UNITY_FLATTEN\n#endif\n#ifndef UNITY_UNROLL\n# define UNITY_UNROLL\n#endif\n#ifndef UNITY_UNROLLX\n# define UNITY_UNROLLX(_x)\n#endif\n#ifndef UNITY_LOOP\n# define UNITY_LOOP\n#endif\n\n\n\n#define _USINGTEXCOORD1 1\n\n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n UNITY_POSITION(pos); // must be named pos because Unity does stupid macro stuff\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n \n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n UNITY_LIGHTING_COORDS(8,9)\n UNITY_FOG_COORDS(10)\n\n \n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD18;\n // #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n\n };\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef UNITY_MATRIX_I_M\n\n #define UNITY_MATRIX_I_M unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)UNITY_MATRIX_V, norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\tfixed3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n \n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n UNITY_SETUP_INSTANCE_ID(v);\n VertexToPixel o;\n UNITY_INITIALIZE_OUTPUT(VertexToPixel,o);\n UNITY_TRANSFER_INSTANCE_ID(v,o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.pos = UnityObjectToClipPos(v.vertex);\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos);\n #endif\n\n o.worldPos = mul(GetObjectToWorldMatrix(), v.vertex).xyz;\n o.worldNormal = UnityObjectToWorldNormal(v.normal);\n o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n\n UNITY_TRANSFER_LIGHTING(o, v.texcoord1.xy); // pass shadow and, possibly, light cookie coordinates to pixel shader\n UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader\n\n return o;\n }\n\n \n\n // fragment shader\n fixed4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n // prepare and unpack data\n\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_EXTRACT_FOG_FROM_TSPACE(IN);\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_EXTRACT_FOG_FROM_WORLD_POS(IN);\n #else\n UNITY_EXTRACT_FOG(IN);\n #endif\n\n\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n\n #ifndef USING_DIRECTIONAL_LIGHT\n fixed3 lightDir = normalize(UnityWorldSpaceLightDir(d.worldSpacePosition));\n #else\n fixed3 lightDir = _WorldSpaceLightPos0.xyz;\n #endif\n float3 worldViewDir = normalize(UnityWorldSpaceViewDir(d.worldSpacePosition));\n\n #if _USESPECULAR || _USESPECULARWORKFLOW || _SPECULARFROMMETALLIC\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandardSpecular o = (SurfaceOutputStandardSpecular)0;\n #else\n SurfaceOutputStandardSpecular o;\n #endif\n o.Specular = l.Specular;\n o.Occlusion = l.Occlusion;\n o.Smoothness = l.Smoothness;\n #elif _BDRFLAMBERT || _BDRF3 || _SIMPLELIT\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutput o = (SurfaceOutput)0;\n #else\n SurfaceOutput o;\n #endif\n\n o.Specular = l.SpecularPower;\n o.Gloss = l.Smoothness;\n _SpecColor.rgb = l.Specular; // fucking hell Unity, wtf..\n #else\n #ifdef UNITY_COMPILER_HLSL\n SurfaceOutputStandard o = (SurfaceOutputStandard)0;\n #else\n SurfaceOutputStandard o;\n #endif\n o.Smoothness = l.Smoothness;\n o.Metallic = l.Metallic;\n o.Occlusion = l.Occlusion;\n #endif\n\n \n o.Albedo = l.Albedo;\n o.Emission = l.Emission;\n o.Alpha = l.Alpha;\n\n #if _WORLDSPACENORMAL\n o.Normal = l.Normal;\n #else\n o.Normal = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n\n\n UNITY_LIGHT_ATTENUATION(atten, IN, d.worldSpacePosition)\n half4 c = 0;\n\n // Setup lighting environment\n UnityGI gi;\n UNITY_INITIALIZE_OUTPUT(UnityGI, gi);\n gi.indirect.diffuse = 0;\n gi.indirect.specular = 0;\n gi.light.color = _LightColor0.rgb;\n gi.light.dir = lightDir;\n gi.light.color *= atten;\n\n #if defined(_OVERRIDE_SHADOWMASK)\n float4 mulColor = saturate(dot(l.ShadowMask, unity_OcclusionMaskSelector));\n gi.light.color *= mulColor;\n #endif\n\n #if _USESPECULAR\n c += LightingStandardSpecular (o, worldViewDir, gi);\n #elif _BDRF3 || _SIMPLELIT\n c += LightingBlinnPhong (o, d.worldSpaceViewDir, gi);\n #else\n c += LightingStandard (o, worldViewDir, gi);\n #endif\n \n\n ChainFinalColorForward(l, d, c);\n\n #if !DISABLEFOG\n UNITY_APPLY_FOG(_unity_fogCoord, c); // apply fog\n #endif\n #if !_ALPHABLEND_ON\n UNITY_OPAQUE_ALPHA(c.a);\n #endif\n \n return c;\n }\n\n ENDCG\n\n }\n\n \n\t Pass {\n\t\t Name \"ShadowCaster\"\n\t\t Tags { \"LightMode\" = \"ShadowCaster\" }\n\t\t ZWrite On ZTest LEqual\n\n \n\n CGPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n // compile directives\n #pragma target 3.0\n #pragma multi_compile_instancing\n #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2\n #pragma multi_compile_shadowcaster\n #include \"HLSLSupport.cginc\"\n #define UNITY_INSTANCED_LOD_FADE\n #define UNITY_INSTANCED_SH\n #define UNITY_INSTANCED_LIGHTMAPSTS\n #include \"UnityShaderVariables.cginc\"\n #include \"UnityShaderUtilities.cginc\"\n\n #include \"UnityCG.cginc\"\n #include \"Lighting.cginc\"\n #include \"UnityPBSLighting.cginc\"\n\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _STANDARD 1\n// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same\n// texturing library they use. However, since they are not included in the standard pipeline by default, there is no\n// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without\n// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead\n// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not\n// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.\n\n#if defined(SHADER_API_GAMECORE)\n\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\t#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r\n\t#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_XBOXONE)\n\t\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_PSSL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n\n#elif defined(SHADER_API_D3D11)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_METAL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_VULKAN)\n// This file assume SHADER_API_VULKAN is defined\n\t// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.\n\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_SWITCH)\n\t// This file assume SHADER_API_SWITCH is defined\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_GLCORE)\n\n\t// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 46)\n\t#define OPENGL4_1_SM5 1\n\t#else\n\t#define OPENGL4_1_SM5 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\n\t#if OPENGL4_1_SM5\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#endif\n\n\n\t#elif defined(SHADER_API_GLES3)\n\n\t// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 40)\n\t#define GLES3_1_AEP 1\n\t#else\n\t#define GLES3_1_AEP 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#if GLES3_1_AEP\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\t#else\n\t#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\t#endif\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#if GLES3_1_AEP\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\t#endif\n\n\n#elif defined(SHADER_API_GLES)\n\n\n\t#define uint int\n\n\t#define rcp(x) 1.0 / (x)\n\t#define ddx_fine ddx\n\t#define ddy_fine ddy\n\t#define asfloat\n\t#define asuint(x) asint(x)\n\t#define f32tof16\n\t#define f16tof32\n\n\t#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray\n\t#define TEXTURECUBE(textureName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray\n\t#define TEXTURE3D(textureName) sampler3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) sampler2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_HALF(textureName) sampler3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\t#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\n\t#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\n\t#define SAMPLER(samplerName)\n\t#define SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)\n\n\t#if (SHADER_TARGET >= 30)\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))\n\t#else\n\t // No lod support. Very poor approximation with bias.\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)\n\t#endif\n\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)\n\t// No lod support. Very poor approximation with bias.\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)\n\n\n\t// Not supported. Can't define as error because shader library is calling these functions.\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)\n\n\t// Gather not supported. Fallback to regular texture sampling.\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\n#else\n#error unsupported shader api\n#endif\n\n\n\n\n// default flow control attributes\n#ifndef UNITY_BRANCH\n# define UNITY_BRANCH\n#endif\n#ifndef UNITY_FLATTEN\n# define UNITY_FLATTEN\n#endif\n#ifndef UNITY_UNROLL\n# define UNITY_UNROLL\n#endif\n#ifndef UNITY_UNROLLX\n# define UNITY_UNROLLX(_x)\n#endif\n#ifndef UNITY_LOOP\n# define UNITY_LOOP\n#endif\n\n\n\n#define _USINGTEXCOORD1 1\n\n\n \n\n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n V2F_SHADOW_CASTER; // may declare TEXCOORD0 for the wonderfully named .vec\n float3 worldPos : TEXCOORD1;\n float3 worldNormal : TEXCOORD2;\n float4 worldTangent : TEXCOORD3;\n float4 texcoord0 : TEXCOORD4;\n float4 texcoord1 : TEXCOORD5;\n // float4 texcoord2 : TEXCOORD6;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD7;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD8;\n #endif\n \n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD16;\n // #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef UNITY_MATRIX_I_M\n\n #define UNITY_MATRIX_I_M unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)UNITY_MATRIX_V, norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\tfixed3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n UNITY_SETUP_INSTANCE_ID(v);\n VertexToPixel o;\n UNITY_INITIALIZE_OUTPUT(VertexToPixel,o);\n UNITY_TRANSFER_INSTANCE_ID(v,o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n \n\n o.worldPos = mul(GetObjectToWorldMatrix(), v.vertex).xyz;\n o.worldNormal = UnityObjectToWorldNormal(v.normal);\n o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n\n // sets o.pos, so do screenpos after.\n TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos);\n #endif\n\n return o;\n }\n\n \n\n // fragment shader\n fixed4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n // prepare and unpack data\n\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_EXTRACT_FOG_FROM_TSPACE(IN);\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_EXTRACT_FOG_FROM_WORLD_POS(IN);\n #else\n UNITY_EXTRACT_FOG(IN);\n #endif\n\n #ifndef USING_DIRECTIONAL_LIGHT\n fixed3 lightDir = normalize(UnityWorldSpaceLightDir(IN.worldPos));\n #else\n fixed3 lightDir = _WorldSpaceLightPos0.xyz;\n #endif\n\n \n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n SHADOW_CASTER_FRAGMENT(IN)\n }\n\n\n ENDCG\n\n }\n\n \n\t // ---- meta information extraction pass:\n\t Pass\n {\n\t\t Name \"Meta\"\n\t\t Tags { \"LightMode\" = \"Meta\" }\n\t\t Cull Off\n\n \n\n CGPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // compile directives\n #pragma target 3.0\n #pragma multi_compile_instancing\n #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2\n #pragma shader_feature EDITOR_VISUALIZATION\n\n #include \"HLSLSupport.cginc\"\n #define UNITY_INSTANCED_LOD_FADE\n #define UNITY_INSTANCED_SH\n #define UNITY_INSTANCED_LIGHTMAPSTS\n #include \"UnityShaderVariables.cginc\"\n #include \"UnityShaderUtilities.cginc\"\n\n #include \"UnityCG.cginc\"\n #include \"Lighting.cginc\"\n #include \"UnityPBSLighting.cginc\"\n #include \"UnityMetaPass.cginc\"\n\n #define _PASSMETA 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _STANDARD 1\n// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same\n// texturing library they use. However, since they are not included in the standard pipeline by default, there is no\n// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without\n// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead\n// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not\n// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.\n\n#if defined(SHADER_API_GAMECORE)\n\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\t#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r\n\t#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_XBOXONE)\n\t\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n#elif defined(SHADER_API_PSSL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n\n\n#elif defined(SHADER_API_D3D11)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_METAL)\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_VULKAN)\n// This file assume SHADER_API_VULKAN is defined\n\t// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.\n\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_SWITCH)\n\t// This file assume SHADER_API_SWITCH is defined\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\n#elif defined(SHADER_API_GLCORE)\n\n\t// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 46)\n\t#define OPENGL4_1_SM5 1\n\t#else\n\t#define OPENGL4_1_SM5 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)\n\t#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\n\t#if OPENGL4_1_SM5\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#endif\n\n\n\t#elif defined(SHADER_API_GLES3)\n\n\t// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html\n\t#if (SHADER_TARGET >= 40)\n\t#define GLES3_1_AEP 1\n\t#else\n\t#define GLES3_1_AEP 0\n\t#endif\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) Texture2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName\n\t#define TEXTURECUBE(textureName) TextureCube textureName\n\t#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName\n\t#define TEXTURE3D(textureName) Texture3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) Texture2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added\n\t#define TEXTURE3D_HALF(textureName) Texture3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)\n\t#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)\n\n\t#if GLES3_1_AEP\n\t#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName\n\t#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName\n\t#else\n\t#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\t#endif\n\n\t#define SAMPLER(samplerName) SamplerState samplerName\n\t#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)\n\t#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)\n\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)\n\t#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\t#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)\n\n\t#ifdef UNITY_NO_CUBEMAP_ARRAY\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#else\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)\n\t#endif\n\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)\n\n\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))\n\n\t#if GLES3_1_AEP\n\t#define PLATFORM_SUPPORT_GATHER\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)\n\t#else\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\t#endif\n\n\n#elif defined(SHADER_API_GLES)\n\n\n\t#define uint int\n\n\t#define rcp(x) 1.0 / (x)\n\t#define ddx_fine ddx\n\t#define ddy_fine ddy\n\t#define asfloat\n\t#define asuint(x) asint(x)\n\t#define f32tof16\n\t#define f16tof32\n\n\t#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0\n\n\t// Initialize arbitrary structure with zero values.\n\t// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0\n\t#define ZERO_INITIALIZE(type, name) name = (type)0;\n\t#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }\n\n\n\t// Texture util abstraction\n\n\t#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2\n\n\t// Texture abstraction\n\n\t#define TEXTURE2D(textureName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray\n\t#define TEXTURECUBE(textureName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray\n\t#define TEXTURE3D(textureName) sampler3D textureName\n\n\t#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName\n\t#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName\n\t#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName\n\n\t#define TEXTURE2D_HALF(textureName) sampler2D_half textureName\n\t#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray\n\t#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName\n\t#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray\n\t#define TEXTURE3D_HALF(textureName) sampler3D_half textureName\n\n\t#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\t#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array\n\n\t#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)\n\t#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)\n\t#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)\n\n\t#define SAMPLER(samplerName)\n\t#define SAMPLER_CMP(samplerName)\n\n\t#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName\n\t#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName\n\t#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName\n\t#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\t#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName\n\n\t#define TEXTURE2D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE3D_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName\n\t#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName\n\n\t#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)\n\n\t#if (SHADER_TARGET >= 30)\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))\n\t#else\n\t // No lod support. Very poor approximation with bias.\n\t #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)\n\t#endif\n\n\t#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))\n\t#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)\n\t#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)\n\t#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)\n\t#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)\n\t#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)\n\t// No lod support. Very poor approximation with bias.\n\t#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)\n\t#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))\n\t#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)\n\t#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)\n\t#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)\n\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)\n\t#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)\n\t#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)\n\t#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)\n\n\n\t// Not supported. Can't define as error because shader library is calling these functions.\n\t#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)\n\t#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)\n\t#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)\n\n\t// Gather not supported. Fallback to regular texture sampling.\n\t#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)\n\t#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)\n\t#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)\n\t#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)\n\t#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)\n\t#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)\n\t#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)\n\t#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)\n\n#else\n#error unsupported shader api\n#endif\n\n\n\n\n// default flow control attributes\n#ifndef UNITY_BRANCH\n# define UNITY_BRANCH\n#endif\n#ifndef UNITY_FLATTEN\n# define UNITY_FLATTEN\n#endif\n#ifndef UNITY_UNROLL\n# define UNITY_UNROLL\n#endif\n#ifndef UNITY_UNROLLX\n# define UNITY_UNROLLX(_x)\n#endif\n#ifndef UNITY_LOOP\n# define UNITY_LOOP\n#endif\n\n\n\n#define _USINGTEXCOORD1 1\n\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n UNITY_POSITION(pos);\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n #ifdef EDITOR_VISUALIZATION\n float2 vizUV : TEXCOORD8;\n float4 lightCoord : TEXCOORD9;\n #endif\n\n \n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD17;\n // #endif\n\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef UNITY_MATRIX_I_M\n\n #define UNITY_MATRIX_I_M unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)UNITY_MATRIX_M, transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)UNITY_MATRIX_V, norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\tfixed3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n UNITY_SETUP_INSTANCE_ID(v);\n VertexToPixel o;\n UNITY_INITIALIZE_OUTPUT(VertexToPixel,o);\n UNITY_TRANSFER_INSTANCE_ID(v,o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n\n o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #ifdef EDITOR_VISUALIZATION\n o.vizUV = 0;\n o.lightCoord = 0;\n if (unity_VisualizationMode == EDITORVIZ_TEXTURE)\n o.vizUV = UnityMetaVizUV(unity_EditorViz_UVIndex, v.texcoord0.xy, v.texcoord1.xy, v.texcoord2.xy, unity_EditorViz_Texture_ST);\n else if (unity_VisualizationMode == EDITORVIZ_SHOWLIGHTMASK)\n {\n o.vizUV = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n o.lightCoord = mul(unity_EditorViz_WorldToLight, mul(GetObjectToWorldMatrix(), float4(v.vertex.xyz, 1)));\n }\n #endif\n\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos);\n #endif\n\n o.worldPos = mul(GetObjectToWorldMatrix(), v.vertex).xyz;\n o.worldNormal = UnityObjectToWorldNormal(v.normal);\n o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n return o;\n }\n\n \n\n // fragment shader\n fixed4 Frag (VertexToPixel IN\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n #ifdef FOG_COMBINED_WITH_TSPACE\n UNITY_EXTRACT_FOG_FROM_TSPACE(IN);\n #elif defined FOG_COMBINED_WITH_WORLD_POS\n UNITY_EXTRACT_FOG_FROM_WORLD_POS(IN);\n #else\n UNITY_EXTRACT_FOG(IN);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n\n Surface l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n \n ChainSurfaceFunction(l, d);\n\n UnityMetaInput metaIN;\n UNITY_INITIALIZE_OUTPUT(UnityMetaInput, metaIN);\n metaIN.Albedo = l.Albedo;\n metaIN.Emission = l.Emission;\n \n #if _USESPECULAR\n metaIN.SpecularColor = l.Specular;\n #endif\n\n #ifdef EDITOR_VISUALIZATION\n metaIN.VizUV = IN.vizUV;\n metaIN.LightCoord = IN.lightCoord;\n #endif\n return UnityMetaFragment(metaIN);\n }\n ENDCG\n\n }\n\n \n\n\n\n\n\n\n\n\n\n\n\n }\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":1,"UnityVersionMin":20212,"UnityVersionMax":20221,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: URP2021\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n [HideInInspector]_QueueOffset(\"_QueueOffset\", Float) = 0\n [HideInInspector]_QueueControl(\"_QueueControl\", Float) = -1\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n }\n SubShader\n {\n Tags { \"RenderPipeline\"=\"UniversalPipeline\" \"RenderType\" = \"Opaque\" \"UniversalMaterialType\" = \"Lit\" \"Queue\" = \"Geometry\" }\n\n \n\n \n Pass\n {\n Name \"Universal Forward\"\n Tags \n { \n \"LightMode\" = \"UniversalForward\"\n }\n Cull Back\n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n Blend One Zero, One Zero\nCull Back\nZTest LEqual\nZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n \n // Keywords\n #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS\n #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _LIGHT_LAYERS\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile_fragment _ _LIGHT_COOKIES\n #pragma multi_compile _ _CLUSTERED_RENDERING\n // GraphKeywords: <None>\n\n #define SHADER_PASS SHADERPASS_FORWARD\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define _PASSFORWARD 1\n #define _FOG_FRAGMENT 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n#if _UNLIT\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl\" \n#endif\n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 1;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n\n \n \n InputData inputData = (InputData)0;\n\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n inputData.shadowCoord = IN.shadowCoord;\n #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(IN.worldPos);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n \n#if _BAKEDLIT\n inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n inputData.vertexLighting = 0;\n#else\n inputData.fogCoord = InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n#endif \n\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #elif _BAKEDLIT\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #endif\n #endif\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n #if !_BAKEDLIT\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n \n #if defined(_OVERRIDE_SHADOWMASK)\n float4 mulColor = saturate(dot(l.ShadowMask, _MainLightOcclusionProbes)); //unity_OcclusionMaskSelector));\n inputData.shadowMask = mulColor;\n #endif\n #else\n inputData.shadowMask = float4(1,1,1,1);\n #endif\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #if _WORLDSPACENORMAL\n float3 normalTS = WorldToTangentSpace(d, l.Normal);\n #else\n float3 normalTS = l.Normal;\n #endif\n\n SurfaceData surface = (SurfaceData)0;\n surface.albedo = l.Albedo;\n surface.metallic = saturate(metallic);\n surface.specular = specular;\n surface.smoothness = saturate(l.Smoothness),\n surface.occlusion = l.Occlusion,\n surface.emission = l.Emission,\n surface.alpha = saturate(l.Alpha);\n surface.clearCoatMask = 0;\n surface.clearCoatSmoothness = 1;\n\n #ifdef _CLEARCOAT\n surface.clearCoatMask = saturate(l.CoatMask);\n surface.clearCoatSmoothness = saturate(l.CoatSmoothness);\n #endif\n\n #if !_UNLIT\n half4 color = half4(l.Albedo, l.Alpha);\n #ifdef _DBUFFER\n #if _BAKEDLIT\n half3 bakeColor = color.rgb;\n float3 bakeNormal = inputData.normalWS.xyz;\n ApplyDecalToBaseColorAndNormal(IN.pos, bakeColor, bakeNormal);\n color.rgb = bakeColor;\n inputData.normalWS.xyz = bakeNormal;\n #else\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n #endif\n #if _SIMPLELIT\n color = UniversalFragmentBlinnPhong(\n inputData,\n surface);\n #elif _BAKEDLIT\n color = UniversalFragmentBakedLit(inputData, color.rgb, color.a, normalTS);\n #else\n color = UniversalFragmentPBR(inputData, surface);\n #endif\n\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n\n #else // unlit\n #ifdef _DBUFFER\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n half4 color = UniversalFragmentUnlit(inputData, l.Albedo, l.Alpha);\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n #endif\n ChainFinalColorForward(l, d, color);\n\n return color;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"GBuffer\"\n Tags\n {\n \"LightMode\" = \"UniversalGBuffer\"\n }\n \n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #pragma multi_compile_fog\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n \n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT\n #pragma multi_compile_fragment _ _LIGHT_LAYERS\n #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n \n #define _FOG_FRAGMENT 1\n\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define SHADERPASS SHADERPASS_GBUFFER\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n \n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl\"\n\n // fragment shader\n FragmentOutput Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) \n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 0;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n InputData inputData = (InputData)0;\n\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n\n //inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #endif\n #endif\n\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #ifdef _DBUFFER\n ApplyDecal(IN.pos,\n l.Albedo,\n specular,\n inputData.normalWS,\n metallic,\n l.Occlusion,\n l.Smoothness);\n #endif\n\n BRDFData brdfData;\n InitializeBRDFData(l.Albedo, metallic, specular, l.Smoothness, l.Alpha, brdfData);\n Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);\n MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);\n half3 color = GlobalIllumination(brdfData, inputData.bakedGI, l.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);\n\n return BRDFDataToGbuffer(brdfData, inputData, l.Smoothness, l.Emission + color, l.Occlusion);\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"ShadowCaster\"\n Tags \n { \n \"LightMode\" = \"ShadowCaster\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n // ColorMask: <None>\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n \n #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW\n\n\n #define _NORMAL_DROPOFF_TS 1\n #define ATTRIBUTES_NEED_NORMAL\n #define ATTRIBUTES_NEED_TANGENT\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n \n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n \n \n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthOnly\"\n Tags \n { \n \"LightMode\" = \"DepthOnly\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n ColorMask 0\n \n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n\n #define _PASSDEPTH 1\n\n #pragma target 3.0\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"Meta\"\n Tags \n { \n \"LightMode\" = \"Meta\"\n }\n\n Cull Off\n \n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n \n #define SHADERPASS SHADERPASS_META\n #define _PASSMETA 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n\n Surface l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n MetaInput metaInput = (MetaInput)0;\n metaInput.Albedo = l.Albedo;\n metaInput.Emission = l.Emission;\n\n return MetaFragment(metaInput);\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthNormals\"\n Tags\n {\n \"LightMode\" = \"DepthNormals\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n\n #define SHADERPASS SHADERPASS_DEPTHNORMALSONLY\n #define _PASSDEPTH 1\n #define _PASSDEPTHNORMALS 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n\n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if defined(_GBUFFER_NORMALS_OCT)\n float3 normalWS = d.worldSpaceNormal;\n float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms\n float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1]\n half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1]\n return half4(packedNormalWS, 0.0);\n #else\n float3 wsn = l.Normal;\n #if !_WORLDSPACENORMAL\n wsn = TangentToWorldSpace(d, l.Normal);\n #endif\n return half4(NormalizeNormalPerPixel(wsn), 0.0);\n #endif\n\n \n }\n\n ENDHLSL\n\n }\n\n\n \n\n\n\n\n\n\n\n\n\n\n \n\n }\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":2,"UnityVersionMin":20212,"UnityVersionMax":20221,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: HDRP2021\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n\n [HideInInspector]_RenderQueueType(\"Float\", Float) = 1\n [HideInInspector][ToggleUI]_AddPrecomputedVelocity(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_DepthOffsetEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentWritingMotionVec(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaCutoffEnable(\"Boolean\", Float) = 0\n [HideInInspector]_TransparentSortPriority(\"_TransparentSortPriority\", Float) = 0\n [HideInInspector][ToggleUI]_UseShadowThreshold(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPrepassEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPostpassEnable(\"Boolean\", Float) = 0\n [HideInInspector]_SurfaceType(\"Float\", Float) = 0\n [HideInInspector]_BlendMode(\"Float\", Float) = 0\n [HideInInspector]_SrcBlend(\"Float\", Float) = 1\n [HideInInspector]_DstBlend(\"Float\", Float) = 0\n [HideInInspector]_AlphaSrcBlend(\"Float\", Float) = 1\n [HideInInspector]_AlphaDstBlend(\"Float\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMask(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMaskInspectorValue(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ZWrite(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_TransparentZWrite(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableFogOnTransparent(\"Boolean\", Float) = 1\n [HideInInspector]_ZTestDepthEqualForOpaque(\"Float\", Int) = 4\n [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)]_ZTestTransparent(\"Float\", Float) = 4\n [HideInInspector][ToggleUI]_TransparentBackfaceEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_RequireSplitLighting(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ReceivesSSR(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_ReceivesSSRTransparent(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableBlendModePreserveSpecularLighting(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_SupportDecals(\"Boolean\", Float) = 1\n [HideInInspector]_StencilRef(\"Float\", Int) = 0\n [HideInInspector]_StencilWriteMask(\"Float\", Int) = 6\n [HideInInspector]_StencilRefDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilWriteMaskDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilRefMV(\"Float\", Int) = 40\n [HideInInspector]_StencilWriteMaskMV(\"Float\", Int) = 40\n [HideInInspector]_StencilRefDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskGBuffer(\"Float\", Int) = 14\n [HideInInspector]_StencilRefGBuffer(\"Float\", Int) = 10\n [HideInInspector]_ZTestGBuffer(\"Float\", Int) = 4\n [HideInInspector][ToggleUI]_RayTracing(\"Boolean\", Float) = 0\n [HideInInspector][Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel(\"Float\", Float) = 0\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n }\n SubShader\n {\n Tags { \"RenderPipeline\" = \"HDRenderPipeline\" \"RenderType\" = \"HDLitShader\" \"Queue\" = \"Geometry+225\" }\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"Forward\"\n Tags { \"LightMode\" = \"Forward\" }\n\n \n \n Stencil\n {\n WriteMask [_StencilWriteMask]\n Ref [_StencilRef]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n \n ColorMask [_ColorMaskTransparentVel] 1\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ DEBUG_DISPLAY\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile_raytracing PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_raytracing _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n #pragma multi_compile_fragment SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH\n #pragma multi_compile_fragment SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON\n #pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST\n \n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_FORWARD\n #define SUPPORT_BLENDMODE_PRESERVE_SPECULAR_LIGHTING\n #define HAS_LIGHTLOOP\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSFORWARD 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n #define VT_BUFFER_TARGET SV_Target1\n #define EXTRA_BUFFER_TARGET SV_Target2\n #else\n #define EXTRA_BUFFER_TARGET SV_Target1\n #endif\n\n\n\n\n void Frag(VertexToPixel v2p,\n #ifdef OUTPUT_SPLIT_LIGHTING\n out float4 outColor : SV_Target0, // outSpecularLighting\n #ifdef UNITY_VIRTUAL_TEXTURING\n out float4 outVTFeedback : VT_BUFFER_TARGET,\n #endif\n out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,\n OUTPUT_SSSBUFFER(outSSSBuffer)\n #else\n out float4 outColor : SV_Target0\n #ifdef UNITY_VIRTUAL_TEXTURING\n ,out float4 outVTFeedback : VT_BUFFER_TARGET\n #endif\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n , out float4 outMotionVec : EXTRA_BUFFER_TARGET\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif // OUTPUT_SPLIT_LIGHTING\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n // Init outMotionVector here to solve compiler warning (potentially unitialized variable)\n // It is init to the value of forceNoMotion (with 2.0)\n outMotionVec = float4(2.0, 0.0, 0.0, 0.0);\n #endif\n\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.\n input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;\n\n uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n \n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n\n PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);\n\n outColor = float4(0.0, 0.0, 0.0, 0.0);\n\n // We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.\n\n #ifdef DEBUG_DISPLAY\n // Init in debug display mode to quiet warning\n #ifdef OUTPUT_SPLIT_LIGHTING\n outDiffuseLighting = 0;\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #endif\n\n \n\n // Same code in ShaderPassForwardUnlit.shader\n // Reminder: _DebugViewMaterialArray[i]\n // i==0 -> the size used in the buffer\n // i>0 -> the index used (0 value means nothing)\n // The index stored in this buffer could either be\n // - a gBufferIndex (always stored in _DebugViewMaterialArray[1] as only one supported)\n // - a property index which is different for each kind of material even if reflecting the same thing (see MaterialSharedProperty)\n bool viewMaterial = false;\n int bufferSize = _DebugViewMaterialArray[0].x;\n if (bufferSize != 0)\n {\n bool needLinearToSRGB = false;\n float3 result = float3(1.0, 0.0, 1.0);\n\n // Loop through the whole buffer\n // Works because GetSurfaceDataDebug will do nothing if the index is not a known one\n for (int index = 1; index <= bufferSize; index++)\n {\n int indexMaterialProperty = _DebugViewMaterialArray[index].x;\n\n // skip if not really in use\n if (indexMaterialProperty != 0)\n {\n viewMaterial = true;\n\n GetPropertiesDataDebug(indexMaterialProperty, result, needLinearToSRGB);\n GetVaryingsDataDebug(indexMaterialProperty, input, result, needLinearToSRGB);\n GetBuiltinDataDebug(indexMaterialProperty, builtinData, posInput, result, needLinearToSRGB);\n GetSurfaceDataDebug(indexMaterialProperty, surfaceData, result, needLinearToSRGB);\n GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB);\n }\n }\n\n // TEMP!\n // For now, the final blit in the backbuffer performs an sRGB write\n // So in the meantime we apply the inverse transform to linear data to compensate.\n if (!needLinearToSRGB)\n result = SRGBToLinear(max(0, result));\n\n outColor = float4(result, 1.0);\n }\n\n if (!viewMaterial)\n {\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR || _DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR)\n {\n float3 result = float3(0.0, 0.0, 0.0);\n\n GetPBRValidatorDebug(surfaceData, result);\n\n outColor = float4(result, 1.0f);\n }\n else if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)\n {\n float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);\n outColor = result;\n }\n else\n #endif\n {\n #ifdef _SURFACE_TYPE_TRANSPARENT\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;\n #else\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;\n #endif\n\n LightLoopOutput lightLoopOutput;\n LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);\n\n float3 diffuseLighting = lightLoopOutput.diffuseLighting;\n float3 specularLighting = lightLoopOutput.specularLighting;\n\n diffuseLighting *= GetCurrentExposureMultiplier();\n specularLighting *= GetCurrentExposureMultiplier();\n\n #ifdef OUTPUT_SPLIT_LIGHTING\n if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))\n {\n outColor = float4(specularLighting, 1.0);\n outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);\n }\n else\n {\n outColor = float4(diffuseLighting + specularLighting, 1.0);\n outDiffuseLighting = 0;\n }\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #else\n outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);\n outColor = EvaluateAtmosphericScattering(posInput, V, outColor);\n #endif\n\n ChainFinalColorForward(l, d, outColor);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);\n // outMotionVec is already initialize at the value of forceNoMotion (see above)\n if (!forceNoMotion)\n {\n float2 motionVec = CalculateMotionVector(v2p.motionVectorCS, v2p.previousPositionCS);\n EncodeMotionVector(motionVec * 0.5, outMotionVec);\n outMotionVec.zw = 1.0;\n }\n #endif\n }\n\n #ifdef DEBUG_DISPLAY\n }\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n outVTFeedback = builtinData.vtPackedFeedback;\n #endif\n }\n\n ENDHLSL\n }\n Pass\n {\n // based on HDLitPass.template\n Name \"GBuffer\"\n Tags { \"LightMode\" = \"GBuffer\" }\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZTest [_ZTestGBuffer]\n Stencil\n {\n WriteMask [_StencilWriteMaskGBuffer]\n Ref [_StencilRefGBuffer]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n \n\n #pragma multi_compile _ LIGHT_LAYERS\n #pragma multi_compile_raytracing _ LIGHT_LAYERS\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ DEBUG_DISPLAY\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile_raytracing PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_raytracing _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n \n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n\n\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_GBUFFER\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n\n\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n void Frag( VertexToPixel v2f,\n OUTPUT_GBUFFER(outGBuffer)\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n \n ENCODE_INTO_GBUFFER(surfaceData, builtinData, posInput.positionSS, outGBuffer);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n }\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"ShadowCaster\"\n Tags { \"LightMode\" = \"ShadowCaster\" }\n\n \n\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZWrite On\n ColorMask 0\n ZClip [_ZClip]\n \n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n //#pragma multi_compile_local _ _ALPHATEST_ON\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_SHADOWS\n #define RAYTRACING_SHADER_GRAPH_HIGH\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n \n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n #endif\n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n\n\n }\n\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"DepthOnly\"\n Tags { \"LightMode\" = \"DepthOnly\" }\n \n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n \n \n ZWrite On\n \n \n // Stencil setup\n Stencil\n {\n WriteMask [_StencilWriteMaskDepth]\n Ref [_StencilRefDepth]\n Comp Always\n Pass Replace\n }\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n \n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n #define RAYTRACING_SHADER_GRAPH_HIGH\n #define _PASSDEPTH 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2p\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n \n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // to prevent stripping\n surfaceData.normalWS *= saturate(l.Albedo.r + 9999);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n }\n\n\n\n ENDHLSL\n }\n\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"META\"\n Tags { \"LightMode\" = \"META\" }\n \n Cull Off\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n\n \n #pragma multi_compile_instancing\n\n //#pragma multi_compile_local _ _ALPHATEST_ON\n\n\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_LIGHT_TRANSPORT\n #define RAYTRACING_SHADER_GRAPH_HIGH\n #define REQUIRE_DEPTH_TEXTURE\n #define _PASSMETA 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n\n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n float4 Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // no debug apply during light transport pass\n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n LightTransportData lightTransportData = GetLightTransportData(surfaceData, builtinData, bsdfData);\n\n // This shader is call two times. Once for getting emissiveColor, the other time to get diffuseColor\n // We use unity_MetaFragmentControl to make the distinction.\n float4 res = float4(0.0, 0.0, 0.0, 1.0);\n\n if (unity_MetaFragmentControl.x)\n {\n // Apply diffuseColor Boost from LightmapSettings.\n // put abs here to silent a warning, no cost, no impact as color is assume to be positive.\n res.rgb = clamp(pow(abs(lightTransportData.diffuseColor), saturate(unity_OneOverOutputBoost)), 0, unity_MaxOutputValue);\n }\n\n if (unity_MetaFragmentControl.y)\n {\n // emissive use HDR format\n res.rgb = lightTransportData.emissiveColor;\n }\n\n return res;\n }\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"SceneSelectionPass\"\n Tags { \"LightMode\" = \"SceneSelectionPass\" }\n \n Cull Off\n ColorMask 0\n\n \n\n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n \n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define SCENESELECTIONPASS\n #define _PASSSCENESELECT 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n \n void Frag( VertexToPixel IN\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #ifdef WRITE_MSAA_DEPTH\n , out float1 depthColor : SV_Target1\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When only WRITE_MSAA_DEPTH is define and not WRITE_NORMAL_BUFFER it mean we are Unlit and only need depth, but we still have normal buffer binded\n , out float4 outNormalBuffer : SV_Target0\n , out float1 depthColor : SV_Target1\n #elif defined(SCENESELECTIONPASS)\n , out float4 outColor : SV_Target0\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n FragInputs input = BuildFragInputs(IN);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(IN, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When we are MSAA depth only without normal buffer\n // Due to the binding order of these two render targets, we need to have them both declared\n outNormalBuffer = float4(0.0, 0.0, 0.0, 1.0);\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #elif defined(SCENESELECTIONPASS)\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"ScenePickingPass\"\n Tags\n {\n \"LightMode\" = \"Picking\"\n }\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n \n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define SCENEPICKINGPASS\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n \n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n\n }\n\n ENDHLSL\n }\n\n Pass\n {\n Name \"MotionVectors\"\n Tags\n {\n \"LightMode\" = \"MotionVectors\"\n }\n \n // Render State\n Cull Back\n ZWrite On\n Stencil\n {\n WriteMask [_StencilWriteMaskMV]\n Ref [_StencilRefMV]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n\n\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n\n #define SHADERPASS SHADERPASS_MOTION_VECTORS\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define VARYINGS_NEED_PASS\n #define _PASSMOTIONVECTOR 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#if defined(WRITE_DECAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target3\n#elif defined(WRITE_DECAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target2\n#else\n#define SV_TARGET_NORMAL SV_Target1\n#endif\n\n// Caution: Motion vector pass is different from Depth prepass, it render normal buffer last instead of decal buffer last\n// and thus, we force a write of 0 if _DISABLE_DECALS so we always write in the decal buffer.\n// This is required as we can't make distinction between deferred (write normal buffer) and forward (write normal buffer)\n// in the context of the motion vector pass. The cost is acceptable as it is only do object with motion vector (usualy skin object)\n// that most of the time use Forward Material (so are already writing motion vector data).\n// So note that here unlike for depth prepass we don't check && !defined(_DISABLE_DECALS)\nvoid Frag( VertexToPixel v2f\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n , out float4 outMotionVector : SV_Target1\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target2\n #endif\n #else\n // When no MSAA, the motion vector is always the first buffer\n , out float4 outMotionVector : SV_Target0\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target1\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_TARGET_NORMAL\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n\n FragInputs input = BuildFragInputs(v2f);\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n #ifdef _DEPTHOFFSET_ON\n v2f.motionVectorCS.w += builtinData.depthOffset;\n v2f.previousPositionCS.w += builtinData.depthOffset;\n #endif\n\n // TODO: How to allow overriden motion vector from GetSurfaceAndBuiltinData ?\n float2 motionVector = CalculateMotionVector(v2f.motionVectorCS, v2f.previousPositionCS);\n\n // Convert from Clip space (-1..1) to NDC 0..1 space.\n // Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space.\n // Note: ((positionCS * 0.5 + 0.5) - (v2f.previousPositionCS * 0.5 + 0.5)) = (motionVector * 0.5)\n EncodeMotionVector(motionVector * 0.5, outMotionVector);\n\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n // Setting the motionVector to a value more than 2 set as a flag for \"force no motion\". This is valid because, given that the velocities are in NDC,\n // a value of >1 can never happen naturally, unless explicitely set. \n if (forceNoMotion)\n outMotionVector = float4(2.0, 0.0, 0.0, 0.0);\n\n // Depth and Alpha to coverage\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif\n #endif\n\n // Normal Buffer Processing\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER)\n DecalPrepassData decalPrepassData;\n // Force a write in decal buffer even if decal is disab. This is a neutral value which have no impact for later pass\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n #endif\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n outDecalBuffer.w = (GetMeshRenderingLightLayer() & 0x000000FF) / 255.0;\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = posInput.deviceDepth;\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"FullScreenDebug\"\n Tags\n {\n \"LightMode\" = \"FullScreenDebug\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite Off\n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n\n #define SHADERPASS SHADERPASS_FULL_SCREEN_DEBUG\n #define _PASSFULLSCREENDEBUG 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n\n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n#if UNITY_VERSION >= UNITY_2021_3_31\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n \n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n \n\n\n // compute world space normal\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs.tangentToWorld[2], alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n \n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n //posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, fragInputs.texCoord1, fragInputs.texCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #if defined(UNITY_VIRTUAL_TEXTURING)\n builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#define DEBUG_DISPLAY\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/FullScreenDebug.hlsl\"\n\n #if !defined(_DEPTHOFFSET_ON)\n [earlydepthstencil] // quad overshading debug mode writes to UAV\n #endif\n void Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz);\n\n #ifdef PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_QUAD_OVERDRAW)\n {\n IncrementQuadOverdrawCounter(posInput.positionSS.xy, input.primitiveID);\n }\n #endif\n }\n\n ENDHLSL\n }\n\n \n\n\n\n\n\n\n\n\n\n\n \n }\n\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":1,"UnityVersionMin":20222,"UnityVersionMax":20223,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: URP2022\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n [HideInInspector]_QueueOffset(\"_QueueOffset\", Float) = 0\n [HideInInspector]_QueueControl(\"_QueueControl\", Float) = -1\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n }\n SubShader\n {\n Tags { \"RenderPipeline\"=\"UniversalPipeline\" \"RenderType\" = \"Opaque\" \"UniversalMaterialType\" = \"Lit\" \"Queue\" = \"Geometry\" }\n\n \n\n \n Pass\n {\n Name \"Universal Forward\"\n Tags \n { \n \"LightMode\" = \"UniversalForward\"\n }\n Cull Back\n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n Blend One Zero, One Zero\nCull Back\nZTest LEqual\nZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n \n // Keywords\n #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS\n #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _LIGHT_LAYERS\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile_fragment _ _LIGHT_COOKIES\n #pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS\n #pragma multi_compile _ _FORWARD_PLUS\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n \n // GraphKeywords: <None>\n\n #define SHADER_PASS SHADERPASS_FORWARD\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define _PASSFORWARD 1\n #define _FOG_FRAGMENT 1\n \n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n#if _UNLIT\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl\" \n#endif\n\n // fragment shader\n void Frag (VertexToPixel IN\n , out half4 outColor : SV_Target0\n #ifdef _WRITE_RENDERING_LAYERS\n , out float4 outRenderingLayers : SV_Target1\n #endif\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 1;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n\n \n \n InputData inputData = (InputData)0;\n\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n inputData.shadowCoord = IN.shadowCoord;\n #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(IN.worldPos);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n \n#if _BAKEDLIT\n inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n inputData.vertexLighting = 0;\n#else\n inputData.fogCoord = InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n#endif \n\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #elif _BAKEDLIT\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #endif\n #endif\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n #if !_BAKEDLIT\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n \n #if defined(_OVERRIDE_SHADOWMASK)\n float4 mulColor = saturate(dot(l.ShadowMask, _MainLightOcclusionProbes)); //unity_OcclusionMaskSelector));\n inputData.shadowMask = mulColor;\n #endif\n #else\n inputData.shadowMask = float4(1,1,1,1);\n #endif\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #if _WORLDSPACENORMAL\n float3 normalTS = WorldToTangentSpace(d, l.Normal);\n #else\n float3 normalTS = l.Normal;\n #endif\n\n SurfaceData surface = (SurfaceData)0;\n surface.albedo = l.Albedo;\n surface.metallic = saturate(metallic);\n surface.specular = specular;\n surface.smoothness = saturate(l.Smoothness),\n surface.occlusion = l.Occlusion,\n surface.emission = l.Emission,\n surface.alpha = saturate(l.Alpha);\n surface.clearCoatMask = 0;\n surface.clearCoatSmoothness = 1;\n\n #ifdef _CLEARCOAT\n surface.clearCoatMask = saturate(l.CoatMask);\n surface.clearCoatSmoothness = saturate(l.CoatSmoothness);\n #endif\n\n #if !_UNLIT\n half4 color = half4(l.Albedo, l.Alpha);\n #ifdef _DBUFFER\n #if _BAKEDLIT\n half3 bakeColor = color.rgb;\n float3 bakeNormal = inputData.normalWS.xyz;\n ApplyDecalToBaseColorAndNormal(IN.pos, bakeColor, bakeNormal);\n color.rgb = bakeColor;\n inputData.normalWS.xyz = bakeNormal;\n #else\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n #endif\n #if _SIMPLELIT\n color = UniversalFragmentBlinnPhong(\n inputData,\n surface);\n #elif _BAKEDLIT\n color = UniversalFragmentBakedLit(inputData, color.rgb, color.a, normalTS);\n #else\n color = UniversalFragmentPBR(inputData, surface);\n #endif\n\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n\n #else // unlit\n #ifdef _DBUFFER\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n half4 color = UniversalFragmentUnlit(inputData, l.Albedo, l.Alpha);\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n #endif\n ChainFinalColorForward(l, d, color);\n\n outColor = color;\n\n #ifdef _WRITE_RENDERING_LAYERS\n uint renderingLayers = GetMeshRenderingLayer();\n outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);\n #endif\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"GBuffer\"\n Tags\n {\n \"LightMode\" = \"UniversalGBuffer\"\n }\n \n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #pragma multi_compile_fog\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n \n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT\n #pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS\n #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n \n\n #define _FOG_FRAGMENT 1\n\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define SHADERPASS SHADERPASS_GBUFFER\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n \n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl\"\n\n // fragment shader\n FragmentOutput Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) \n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 0;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n InputData inputData = (InputData)0;\n\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n\n //inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #endif\n #endif\n\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #ifdef _DBUFFER\n ApplyDecal(IN.pos,\n l.Albedo,\n specular,\n inputData.normalWS,\n metallic,\n l.Occlusion,\n l.Smoothness);\n #endif\n\n BRDFData brdfData;\n InitializeBRDFData(l.Albedo, metallic, specular, l.Smoothness, l.Alpha, brdfData);\n Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);\n MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);\n half3 color = GlobalIllumination(brdfData, inputData.bakedGI, l.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);\n\n return BRDFDataToGbuffer(brdfData, inputData, l.Smoothness, l.Emission + color, l.Occlusion);\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"ShadowCaster\"\n Tags \n { \n \"LightMode\" = \"ShadowCaster\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n // ColorMask: <None>\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n \n #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n \n\n #define _NORMAL_DROPOFF_TS 1\n #define ATTRIBUTES_NEED_NORMAL\n #define ATTRIBUTES_NEED_TANGENT\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n \n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthOnly\"\n Tags \n { \n \"LightMode\" = \"DepthOnly\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n ColorMask 0\n \n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n\n #define _PASSDEPTH 1\n\n #pragma target 3.0\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"Meta\"\n Tags \n { \n \"LightMode\" = \"Meta\"\n }\n\n Cull Off\n \n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n \n #define SHADERPASS SHADERPASS_META\n #define _PASSMETA 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n\n Surface l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n MetaInput metaInput = (MetaInput)0;\n metaInput.Albedo = l.Albedo;\n metaInput.Emission = l.Emission;\n\n return MetaFragment(metaInput);\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthNormals\"\n Tags\n {\n \"LightMode\" = \"DepthNormals\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #pragma target 3.0\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n #pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS\n \n\n #define SHADERPASS SHADERPASS_DEPTHNORMALSONLY\n #define _PASSDEPTH 1\n #define _PASSDEPTHNORMALS 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n \n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n\n#if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n#endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = TransformObjectToWorld(v.vertex.xyz);\n o.worldNormal = TransformObjectToWorldNormal(v.normal);\n o.worldTangent = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n void Frag (VertexToPixel IN\n , out half4 outNormalWS : SV_Target0\n #ifdef _WRITE_RENDERING_LAYERS\n , out float4 outRenderingLayers : SV_Target1\n #endif\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if defined(_GBUFFER_NORMALS_OCT)\n float3 normalWS = d.worldSpaceNormal;\n float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms\n float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1]\n half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1]\n outNormalWS = half4(packedNormalWS, 0.0);\n #else\n float3 wsn = l.Normal;\n #if !_WORLDSPACENORMAL\n wsn = TangentToWorldSpace(d, l.Normal);\n #endif\n outNormalWS = half4(NormalizeNormalPerPixel(wsn), 0.0);\n #endif\n\n #ifdef _WRITE_RENDERING_LAYERS\n uint renderingLayers = GetMeshRenderingLayer();\n outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);\n #endif\n\n \n }\n\n ENDHLSL\n\n }\n\n\n \n\n\n\n\n\n\n\n\n\n\n \n\n }\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":2,"UnityVersionMin":20222,"UnityVersionMax":20223,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: HDRP2022\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n\n [HideInInspector]_RenderQueueType(\"Float\", Float) = 1\n [HideInInspector][ToggleUI]_AddPrecomputedVelocity(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_DepthOffsetEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentWritingMotionVec(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaCutoffEnable(\"Boolean\", Float) = 0\n [HideInInspector]_TransparentSortPriority(\"_TransparentSortPriority\", Float) = 0\n [HideInInspector][ToggleUI]_UseShadowThreshold(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPrepassEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPostpassEnable(\"Boolean\", Float) = 0\n [HideInInspector]_SurfaceType(\"Float\", Float) = 0\n [HideInInspector]_BlendMode(\"Float\", Float) = 0\n [HideInInspector]_SrcBlend(\"Float\", Float) = 1\n [HideInInspector]_DstBlend(\"Float\", Float) = 0\n [HideInInspector]_AlphaSrcBlend(\"Float\", Float) = 1\n [HideInInspector]_AlphaDstBlend(\"Float\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMask(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMaskInspectorValue(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ZWrite(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_TransparentZWrite(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableFogOnTransparent(\"Boolean\", Float) = 1\n [HideInInspector]_ZTestDepthEqualForOpaque(\"Float\", Int) = 4\n [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)]_ZTestTransparent(\"Float\", Float) = 4\n [HideInInspector][ToggleUI]_TransparentBackfaceEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_RequireSplitLighting(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ReceivesSSR(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_ReceivesSSRTransparent(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableBlendModePreserveSpecularLighting(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_SupportDecals(\"Boolean\", Float) = 1\n [HideInInspector]_StencilRef(\"Float\", Int) = 0\n [HideInInspector]_StencilWriteMask(\"Float\", Int) = 6\n [HideInInspector]_StencilRefDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilWriteMaskDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilRefMV(\"Float\", Int) = 40\n [HideInInspector]_StencilWriteMaskMV(\"Float\", Int) = 40\n [HideInInspector]_StencilRefDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskGBuffer(\"Float\", Int) = 14\n [HideInInspector]_StencilRefGBuffer(\"Float\", Int) = 10\n [HideInInspector]_ZTestGBuffer(\"Float\", Int) = 4\n [HideInInspector][ToggleUI]_RayTracing(\"Boolean\", Float) = 0\n [HideInInspector][Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel(\"Float\", Float) = 0\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n }\n SubShader\n {\n Tags { \"RenderPipeline\" = \"HDRenderPipeline\" \"RenderType\" = \"HDLitShader\" \"Queue\" = \"Geometry+225\" }\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"Forward\"\n Tags { \"LightMode\" = \"Forward\" }\n\n \n \n Stencil\n {\n WriteMask [_StencilWriteMask]\n Ref [_StencilRef]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n \n ColorMask [_ColorMaskTransparentVel] 1\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n\n #pragma target 4.5\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n \n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ DEBUG_DISPLAY\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile_raytracing PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_raytracing _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n #pragma multi_compile_fragment SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH\n #pragma multi_compile_fragment SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON\n #pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST\n #pragma multi_compile_fragment AREA_SHADOW_MEDIUM AREA_SHADOW_HIGH\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n \n \n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_FORWARD\n #define SUPPORT_BLENDMODE_PRESERVE_SPECULAR_LIGHTING\n #define HAS_LIGHTLOOP\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSFORWARD 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n #define VT_BUFFER_TARGET SV_Target1\n #define EXTRA_BUFFER_TARGET SV_Target2\n #else\n #define EXTRA_BUFFER_TARGET SV_Target1\n #endif\n\n\n\n\n void Frag(VertexToPixel v2p,\n #ifdef OUTPUT_SPLIT_LIGHTING\n out float4 outColor : SV_Target0, // outSpecularLighting\n #ifdef UNITY_VIRTUAL_TEXTURING\n out float4 outVTFeedback : VT_BUFFER_TARGET,\n #endif\n out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,\n OUTPUT_SSSBUFFER(outSSSBuffer)\n #else\n out float4 outColor : SV_Target0\n #ifdef UNITY_VIRTUAL_TEXTURING\n ,out float4 outVTFeedback : VT_BUFFER_TARGET\n #endif\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n , out float4 outMotionVec : EXTRA_BUFFER_TARGET\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif // OUTPUT_SPLIT_LIGHTING\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n // Init outMotionVector here to solve compiler warning (potentially unitialized variable)\n // It is init to the value of forceNoMotion (with 2.0)\n outMotionVec = float4(2.0, 0.0, 0.0, 0.0);\n #endif\n\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.\n input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;\n\n uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n \n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n\n PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);\n\n outColor = float4(0.0, 0.0, 0.0, 0.0);\n\n // We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.\n\n #ifdef DEBUG_DISPLAY\n // Init in debug display mode to quiet warning\n #ifdef OUTPUT_SPLIT_LIGHTING\n outDiffuseLighting = 0;\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #endif\n\n \n\n // Same code in ShaderPassForwardUnlit.shader\n // Reminder: _DebugViewMaterialArray[i]\n // i==0 -> the size used in the buffer\n // i>0 -> the index used (0 value means nothing)\n // The index stored in this buffer could either be\n // - a gBufferIndex (always stored in _DebugViewMaterialArray[1] as only one supported)\n // - a property index which is different for each kind of material even if reflecting the same thing (see MaterialSharedProperty)\n bool viewMaterial = false;\n int bufferSize = _DebugViewMaterialArray[0].x;\n if (bufferSize != 0)\n {\n bool needLinearToSRGB = false;\n float3 result = float3(1.0, 0.0, 1.0);\n\n // Loop through the whole buffer\n // Works because GetSurfaceDataDebug will do nothing if the index is not a known one\n for (int index = 1; index <= bufferSize; index++)\n {\n int indexMaterialProperty = _DebugViewMaterialArray[index].x;\n\n // skip if not really in use\n if (indexMaterialProperty != 0)\n {\n viewMaterial = true;\n\n GetPropertiesDataDebug(indexMaterialProperty, result, needLinearToSRGB);\n GetVaryingsDataDebug(indexMaterialProperty, input, result, needLinearToSRGB);\n GetBuiltinDataDebug(indexMaterialProperty, builtinData, posInput, result, needLinearToSRGB);\n GetSurfaceDataDebug(indexMaterialProperty, surfaceData, result, needLinearToSRGB);\n GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB);\n }\n }\n\n // TEMP!\n // For now, the final blit in the backbuffer performs an sRGB write\n // So in the meantime we apply the inverse transform to linear data to compensate.\n if (!needLinearToSRGB)\n result = SRGBToLinear(max(0, result));\n\n outColor = float4(result, 1.0);\n }\n\n if (!viewMaterial)\n {\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR || _DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR)\n {\n float3 result = float3(0.0, 0.0, 0.0);\n\n GetPBRValidatorDebug(surfaceData, result);\n\n outColor = float4(result, 1.0f);\n }\n else if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)\n {\n float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);\n outColor = result;\n }\n else\n #endif\n {\n #ifdef _SURFACE_TYPE_TRANSPARENT\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;\n #else\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;\n #endif\n\n LightLoopOutput lightLoopOutput;\n LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);\n\n float3 diffuseLighting = lightLoopOutput.diffuseLighting;\n float3 specularLighting = lightLoopOutput.specularLighting;\n\n diffuseLighting *= GetCurrentExposureMultiplier();\n specularLighting *= GetCurrentExposureMultiplier();\n\n #ifdef OUTPUT_SPLIT_LIGHTING\n if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))\n {\n outColor = float4(specularLighting, 1.0);\n outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);\n }\n else\n {\n outColor = float4(diffuseLighting + specularLighting, 1.0);\n outDiffuseLighting = 0;\n }\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #else\n outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);\n outColor = EvaluateAtmosphericScattering(posInput, V, outColor);\n #endif\n\n ChainFinalColorForward(l, d, outColor);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);\n // outMotionVec is already initialize at the value of forceNoMotion (see above)\n if (!forceNoMotion)\n {\n float2 motionVec = CalculateMotionVector(v2p.motionVectorCS, v2p.previousPositionCS);\n EncodeMotionVector(motionVec * 0.5, outMotionVec);\n outMotionVec.zw = 1.0;\n }\n #endif\n }\n\n #ifdef DEBUG_DISPLAY\n }\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n outVTFeedback = builtinData.vtPackedFeedback;\n #endif\n }\n\n ENDHLSL\n }\n Pass\n {\n // based on HDLitPass.template\n Name \"GBuffer\"\n Tags { \"LightMode\" = \"GBuffer\" }\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZTest [_ZTestGBuffer]\n ColorMask [_LightLayersMaskBuffer4] 4\n ColorMask [_LightLayersMaskBuffer5] 5\n Stencil\n {\n WriteMask [_StencilWriteMaskGBuffer]\n Ref [_StencilRefGBuffer]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n ColorMask [_LightLayersMaskBuffer4] 4\n ColorMask [_LightLayersMaskBuffer5] 5\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n #pragma target 4.5\n\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n #pragma multi_compile _ LIGHT_LAYERS\n //#pragma multi_compile_raytracing _ LIGHT_LAYERS\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ DEBUG_DISPLAY\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n \n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n\n\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_GBUFFER\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n\n\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n void Frag( VertexToPixel v2f,\n OUTPUT_GBUFFER(outGBuffer)\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n \n ENCODE_INTO_GBUFFER(surfaceData, builtinData, posInput.positionSS, outGBuffer);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n }\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"ShadowCaster\"\n Tags { \"LightMode\" = \"ShadowCaster\" }\n\n \n\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZWrite On\n ColorMask 0\n ZClip [_ZClip]\n \n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n //#pragma multi_compile_local _ _ALPHATEST_ON\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_SHADOWS\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n \n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n #endif\n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n\n\n }\n\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"DepthOnly\"\n Tags { \"LightMode\" = \"DepthOnly\" }\n \n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n \n \n ZWrite On\n \n \n // Stencil setup\n Stencil\n {\n WriteMask [_StencilWriteMaskDepth]\n Ref [_StencilRefDepth]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n AlphaToMask [_AlphaCutoffEnable]\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n #define _PASSDEPTH 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2p\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : DEPTH_OFFSET_SEMANTIC\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // to prevent stripping\n surfaceData.normalWS *= saturate(l.Albedo.r + 9999);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = unity_SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n }\n\n\n\n ENDHLSL\n }\n\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"META\"\n Tags { \"LightMode\" = \"META\" }\n \n Cull Off\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n\n \n #pragma multi_compile_instancing\n\n //#pragma multi_compile_local _ _ALPHATEST_ON\n\n\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_LIGHT_TRANSPORT\n #define RAYTRACING_SHADER_GRAPH_HIGH\n #define REQUIRE_DEPTH_TEXTURE\n #define _PASSMETA 1\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n\n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n float4 Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // no debug apply during light transport pass\n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n LightTransportData lightTransportData = GetLightTransportData(surfaceData, builtinData, bsdfData);\n\n // This shader is call two times. Once for getting emissiveColor, the other time to get diffuseColor\n // We use unity_MetaFragmentControl to make the distinction.\n float4 res = float4(0.0, 0.0, 0.0, 1.0);\n\n if (unity_MetaFragmentControl.x)\n {\n // Apply diffuseColor Boost from LightmapSettings.\n // put abs here to silent a warning, no cost, no impact as color is assume to be positive.\n res.rgb = clamp(pow(abs(lightTransportData.diffuseColor), saturate(unity_OneOverOutputBoost)), 0, unity_MaxOutputValue);\n }\n\n if (unity_MetaFragmentControl.y)\n {\n // emissive use HDR format\n res.rgb = lightTransportData.emissiveColor;\n }\n\n return res;\n }\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"SceneSelectionPass\"\n Tags { \"LightMode\" = \"SceneSelectionPass\" }\n \n Cull Off\n ColorMask 0\n\n \n\n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n \n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define SCENESELECTIONPASS\n #define _PASSSCENESELECT 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n \n void Frag( VertexToPixel IN\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #ifdef WRITE_MSAA_DEPTH\n , out float1 depthColor : SV_Target1\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When only WRITE_MSAA_DEPTH is define and not WRITE_NORMAL_BUFFER it mean we are Unlit and only need depth, but we still have normal buffer binded\n , out float4 outNormalBuffer : SV_Target0\n , out float1 depthColor : SV_Target1\n #elif defined(SCENESELECTIONPASS)\n , out float4 outColor : SV_Target0\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n FragInputs input = BuildFragInputs(IN);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(IN, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When we are MSAA depth only without normal buffer\n // Due to the binding order of these two render targets, we need to have them both declared\n outNormalBuffer = float4(0.0, 0.0, 0.0, 1.0);\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #elif defined(SCENESELECTIONPASS)\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"ScenePickingPass\"\n Tags\n {\n \"LightMode\" = \"Picking\"\n }\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define SCENEPICKINGPASS\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n \n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n DecalPrepassData decalPrepassData;\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n\n }\n\n ENDHLSL\n }\n\n Pass\n {\n Name \"MotionVectors\"\n Tags\n {\n \"LightMode\" = \"MotionVectors\"\n }\n \n // Render State\n Cull Back\n ZWrite On\n Stencil\n {\n WriteMask [_StencilWriteMaskMV]\n Ref [_StencilRefMV]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n\n #define SHADERPASS SHADERPASS_MOTION_VECTORS\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define VARYINGS_NEED_PASS\n #define _PASSMOTIONVECTOR 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#if defined(WRITE_DECAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target3\n#elif defined(WRITE_DECAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target2\n#else\n#define SV_TARGET_NORMAL SV_Target1\n#endif\n\n// Caution: Motion vector pass is different from Depth prepass, it render normal buffer last instead of decal buffer last\n// and thus, we force a write of 0 if _DISABLE_DECALS so we always write in the decal buffer.\n// This is required as we can't make distinction between deferred (write normal buffer) and forward (write normal buffer)\n// in the context of the motion vector pass. The cost is acceptable as it is only do object with motion vector (usualy skin object)\n// that most of the time use Forward Material (so are already writing motion vector data).\n// So note that here unlike for depth prepass we don't check && !defined(_DISABLE_DECALS)\nvoid Frag( VertexToPixel v2f\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n , out float4 outMotionVector : SV_Target1\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target2\n #endif\n #else\n // When no MSAA, the motion vector is always the first buffer\n , out float4 outMotionVector : SV_Target0\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target1\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_TARGET_NORMAL\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n\n FragInputs input = BuildFragInputs(v2f);\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n #ifdef _DEPTHOFFSET_ON\n v2f.motionVectorCS.w += builtinData.depthOffset;\n v2f.previousPositionCS.w += builtinData.depthOffset;\n #endif\n\n // TODO: How to allow overriden motion vector from GetSurfaceAndBuiltinData ?\n float2 motionVector = CalculateMotionVector(v2f.motionVectorCS, v2f.previousPositionCS);\n\n // Convert from Clip space (-1..1) to NDC 0..1 space.\n // Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space.\n // Note: ((positionCS * 0.5 + 0.5) - (v2f.previousPositionCS * 0.5 + 0.5)) = (motionVector * 0.5)\n EncodeMotionVector(motionVector * 0.5, outMotionVector);\n\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n // Setting the motionVector to a value more than 2 set as a flag for \"force no motion\". This is valid because, given that the velocities are in NDC,\n // a value of >1 can never happen naturally, unless explicitely set. \n if (forceNoMotion)\n outMotionVector = float4(2.0, 0.0, 0.0, 0.0);\n\n // Depth and Alpha to coverage\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif\n #endif\n\n // Normal Buffer Processing\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER)\n DecalPrepassData decalPrepassData;\n // Force a write in decal buffer even if decal is disab. This is a neutral value which have no impact for later pass\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.decalLayerMask = GetMeshRenderingDecalLayer();\n #endif\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n outDecalBuffer.w = (GetMeshRenderingLightLayer() & 0x000000FF) / 255.0;\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = posInput.deviceDepth;\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"FullScreenDebug\"\n Tags\n {\n \"LightMode\" = \"FullScreenDebug\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite Off\n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n\n\n\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n \n\n #define SHADERPASS SHADERPASS_FULL_SCREEN_DEBUG\n #define _PASSFULLSCREENDEBUG 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl\"\n\n#if UNITY_VERSION >= 202239\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n#else\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphHeader.hlsl\" \n#endif \n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#define DEBUG_DISPLAY\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/FullScreenDebug.hlsl\"\n\n #if !defined(_DEPTHOFFSET_ON)\n [earlydepthstencil] // quad overshading debug mode writes to UAV\n #endif\n void Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz);\n\n #ifdef PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_QUAD_OVERDRAW)\n {\n IncrementQuadOverdrawCounter(posInput.positionSS.xy, input.primitiveID);\n }\n #endif\n }\n\n ENDHLSL\n }\n\n \n\n\n\n\n\n\n\n\n\n\n \n }\n\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":1,"UnityVersionMin":20233,"UnityVersionMax":30000,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: URP2023\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n [HideInInspector]_QueueOffset(\"_QueueOffset\", Float) = 0\n [HideInInspector]_QueueControl(\"_QueueControl\", Float) = -1\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n }\n SubShader\n {\n Tags { \"RenderPipeline\"=\"UniversalPipeline\" \"RenderType\" = \"Opaque\" \"UniversalMaterialType\" = \"Lit\" \"Queue\" = \"Geometry\" }\n\n \n\n \n Pass\n {\n Name \"Universal Forward\"\n Tags \n { \n \"LightMode\" = \"UniversalForward\"\n }\n Cull Back\n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n Blend One Zero, One Zero\nCull Back\nZTest LEqual\nZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n \n // Keywords\n #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS\n #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_MEDIUM\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_HIGH\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _LIGHT_LAYERS\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile_fragment _ _LIGHT_COOKIES\n #pragma multi_compile _ _FORWARD_PLUS\n #pragma multi_compile _ EVALUATE_SH_VERTEX\n #pragma multi_compile _ EVALUATE_SH_MIXED\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n\n \n // GraphKeywords: <None>\n\n #define SHADER_PASS SHADERPASS_FORWARD\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define _PASSFORWARD 1\n #define _FOG_FRAGMENT 1\n \n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n \n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ProbeVolumeVariants.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n#if _UNLIT\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl\" \n#endif\n\n // fragment shader\n void Frag (VertexToPixel IN\n , out half4 outColor : SV_Target0\n #ifdef _WRITE_RENDERING_LAYERS\n , out float4 outRenderingLayers : SV_Target1\n #endif\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 1;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n\n \n \n InputData inputData = (InputData)0;\n\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n inputData.shadowCoord = IN.shadowCoord;\n #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(IN.worldPos);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n \n#if _BAKEDLIT\n inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n inputData.vertexLighting = 0;\n#else\n inputData.fogCoord = InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n#endif \n\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #elif _BAKEDLIT\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))\n #if UNITY_VERSION >= 60000009\n inputData.bakedGI = SAMPLE_GI(IN.sh, IN.worldPos, inputData.normalWS, inputData.viewDirectionWS, IN.pos, IN.probeOcclusion, inputData.shadowMask);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.sh, IN.worldPos, inputData.normalWS, inputData.viewDirectionWS, IN.pos);\n #endif\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n #endif\n #endif\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n #if !_BAKEDLIT\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n \n #if defined(_OVERRIDE_SHADOWMASK)\n float4 mulColor = saturate(dot(l.ShadowMask, _MainLightOcclusionProbes)); //unity_OcclusionMaskSelector));\n inputData.shadowMask = mulColor;\n #endif\n #else\n inputData.shadowMask = float4(1,1,1,1);\n #endif\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #if _WORLDSPACENORMAL\n float3 normalTS = WorldToTangentSpace(d, l.Normal);\n #else\n float3 normalTS = l.Normal;\n #endif\n\n SurfaceData surface = (SurfaceData)0;\n surface.albedo = l.Albedo;\n surface.metallic = saturate(metallic);\n surface.specular = specular;\n surface.smoothness = saturate(l.Smoothness),\n surface.occlusion = l.Occlusion,\n surface.emission = l.Emission,\n surface.alpha = saturate(l.Alpha);\n surface.clearCoatMask = 0;\n surface.clearCoatSmoothness = 1;\n\n #ifdef _CLEARCOAT\n surface.clearCoatMask = saturate(l.CoatMask);\n surface.clearCoatSmoothness = saturate(l.CoatSmoothness);\n #endif\n\n #if !_UNLIT\n half4 color = half4(l.Albedo, l.Alpha);\n #ifdef _DBUFFER\n #if _BAKEDLIT\n half3 bakeColor = color.rgb;\n float3 bakeNormal = inputData.normalWS.xyz;\n ApplyDecalToBaseColorAndNormal(IN.pos, bakeColor, bakeNormal);\n color.rgb = bakeColor;\n inputData.normalWS.xyz = bakeNormal;\n #else\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n #endif\n #if _SIMPLELIT\n color = UniversalFragmentBlinnPhong(\n inputData,\n surface);\n #elif _BAKEDLIT\n color = UniversalFragmentBakedLit(inputData, color.rgb, color.a, normalTS);\n #else\n color = UniversalFragmentPBR(inputData, surface);\n #endif\n\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n\n #else // unlit\n #ifdef _DBUFFER\n ApplyDecalToSurfaceData(IN.pos, surface, inputData);\n #endif\n half4 color = UniversalFragmentUnlit(inputData, l.Albedo, l.Alpha);\n #if !DISABLEFOG\n color.rgb = MixFog(color.rgb, inputData.fogCoord);\n #endif\n #endif\n ChainFinalColorForward(l, d, color);\n\n outColor = color;\n\n #ifdef _WRITE_RENDERING_LAYERS\n uint renderingLayers = GetMeshRenderingLayer();\n outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);\n #endif\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"GBuffer\"\n Tags\n {\n \"LightMode\" = \"UniversalGBuffer\"\n }\n \n Blend One Zero\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile_fog\n #pragma instancing_options renderinglayer\n \n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING\n #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION\n #pragma multi_compile_fragment _ _SHADOWS_SOFT\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_MEDIUM\n #pragma multi_compile_fragment _ _SHADOWS_SOFT_HIGH\n #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING\n #pragma multi_compile _ SHADOWS_SHADOWMASK\n #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE\n #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3\n #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT\n #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED\n #pragma multi_compile_fragment _ DEBUG_DISPLAY\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n \n\n #define _FOG_FRAGMENT 1\n\n #define VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n #define SHADERPASS SHADERPASS_GBUFFER\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n \n\n // Includes\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ProbeVolumeVariants.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl\"\n\n // fragment shader\n FragmentOutput Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) \n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if _USESPECULAR || _SIMPLELIT\n float3 specular = l.Specular;\n float metallic = 0;\n #else \n float3 specular = 0;\n float metallic = l.Metallic;\n #endif\n\n InputData inputData = (InputData)0;\n inputData.positionCS = IN.pos;\n inputData.positionWS = IN.worldPos;\n #if _WORLDSPACENORMAL\n inputData.normalWS = l.Normal;\n #else\n inputData.normalWS = normalize(TangentToWorldSpace(d, l.Normal));\n #endif\n\n inputData.viewDirectionWS = SafeNormalize(d.worldSpaceViewDir);\n\n\n #if defined(MAIN_LIGHT_CALCULATE_SHADOWS)\n inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);\n #else\n inputData.shadowCoord = float4(0, 0, 0, 0);\n #endif\n\n //inputData.fogCoord = IN.fogFactorAndVertexLight.x;\n InitializeInputDataFog(float4(IN.worldPos, 1.0), IN.fogFactorAndVertexLight.x);\n inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;\n\n\n #if defined(_OVERRIDE_BAKEDGI)\n inputData.bakedGI = l.DiffuseGI;\n l.Emission += l.SpecularGI;\n #else\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.dynamicLightmapUV.xy, IN.sh, inputData.normalWS);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n\t\t #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))\n #if UNITY_VERSION >= 60000009\n inputData.bakedGI = SAMPLE_GI(IN.sh, IN.worldPos, inputData.normalWS, inputData.viewDirectionWS, IN.pos.xy, IN.probeOcclusion, inputData.shadowMask);\n #else\n inputData.bakedGI = SAMPLE_GI(IN.sh, IN.worldPos, inputData.normalWS, inputData.viewDirectionWS, IN.pos);\n #endif\n #else\n inputData.bakedGI = SAMPLE_GI(IN.lightmapUV, IN.sh, inputData.normalWS);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n #endif\n #endif\n\n inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.pos);\n inputData.shadowMask = SAMPLE_SHADOWMASK(IN.lightmapUV);\n\n #if defined(DEBUG_DISPLAY)\n #if defined(DYNAMICLIGHTMAP_ON)\n inputData.dynamicLightmapUV = IN.dynamicLightmapUV.xy;\n #endif\n #if defined(LIGHTMAP_ON)\n inputData.staticLightmapUV = IN.lightmapUV;\n #else\n inputData.vertexSH = IN.sh;\n #endif\n #endif\n\n #ifdef _DBUFFER\n ApplyDecal(IN.pos,\n l.Albedo,\n specular,\n inputData.normalWS,\n metallic,\n l.Occlusion,\n l.Smoothness);\n #endif\n\n BRDFData brdfData;\n InitializeBRDFData(l.Albedo, metallic, specular, l.Smoothness, l.Alpha, brdfData);\n Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);\n MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);\n half3 color = GlobalIllumination(brdfData, inputData.bakedGI, l.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);\n\n return BRDFDataToGbuffer(brdfData, inputData, l.Smoothness, l.Emission + color, l.Occlusion);\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"ShadowCaster\"\n Tags \n { \n \"LightMode\" = \"ShadowCaster\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n // ColorMask: <None>\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n \n #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n\n #define _NORMAL_DROPOFF_TS 1\n #define ATTRIBUTES_NEED_NORMAL\n #define ATTRIBUTES_NEED_TANGENT\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthOnly\"\n Tags \n { \n \"LightMode\" = \"DepthOnly\"\n }\n \n // Render State\n Blend One Zero, One Zero\n Cull Back\n ZTest LEqual\n ZWrite On\n ColorMask 0\n \n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n\n #define _PASSDEPTH 1\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_instancing\n #if (!defined(SHADER_API_GLES) && !defined(SHADER_API_GLES3) && !defined(SHADER_API_GLES30))\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #endif\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n // Includes\n //#include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n //#include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n return 0;\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"Meta\"\n Tags \n { \n \"LightMode\" = \"Meta\"\n }\n\n Cull Off\n \n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n \n #define SHADERPASS SHADERPASS_META\n #define _PASSMETA 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n\n // Includes\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n half4 Frag (VertexToPixel IN\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n\n Surface l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n MetaInput metaInput = (MetaInput)0;\n metaInput.Albedo = l.Albedo;\n metaInput.Emission = l.Emission;\n\n return MetaFragment(metaInput);\n\n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"DepthNormals\"\n Tags\n {\n \"LightMode\" = \"DepthNormals\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite On\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n\n #pragma prefer_hlslcc gles\n #pragma exclude_renderers d3d11_9x\n #pragma multi_compile_fog\n #pragma multi_compile_instancing\n #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE\n #pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS\n\n #define SHADERPASS SHADERPASS_DEPTHNORMALSONLY\n #define _PASSDEPTH 1\n #define _PASSDEPTHNORMALS 1\n\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n // this has to be here or specular color will be ignored. Not in SG code\n #if _SIMPLELIT\n #define _SPECULAR_COLOR\n #endif\n\n\n // Includes\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl\"\n \n \n\n \n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n \n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n\n // fragment shader\n void Frag (VertexToPixel IN\n , out half4 outNormalWS : SV_Target0\n #ifdef _WRITE_RENDERING_LAYERS\n , out float4 outRenderingLayers : SV_Target1\n #endif\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_INSTANCE_ID(IN);\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n\n #if defined(LOD_FADE_CROSSFADE)\n LODFadeCrossFade(IN.pos);\n #endif\n\n ShaderData d = CreateShaderData(IN\n #if NEED_FACING\n , facing\n #endif\n );\n Surface l = (Surface)0;\n\n #ifdef _DEPTHOFFSET_ON\n l.outputDepth = outputDepth;\n #endif\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n\n ChainSurfaceFunction(l, d);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #if defined(_GBUFFER_NORMALS_OCT)\n float3 normalWS = d.worldSpaceNormal;\n float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms\n float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1]\n half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1]\n outNormalWS = half4(packedNormalWS, 0.0);\n #else\n float3 wsn = l.Normal;\n #if !_WORLDSPACENORMAL\n wsn = TangentToWorldSpace(d, l.Normal);\n #endif\n outNormalWS = half4(NormalizeNormalPerPixel(wsn), 0.0);\n #endif\n\n #ifdef _WRITE_RENDERING_LAYERS\n uint renderingLayers = GetMeshRenderingLayer();\n outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);\n #endif\n\n \n }\n\n ENDHLSL\n\n }\n\n\n \n Pass\n {\n Name \"MotionVectors\"\n Tags\n {\n \"LightMode\" = \"MotionVectors\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite On\n ColorMask RG\n\n \n\n HLSLPROGRAM\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n #define _PASSMOTIONVECTOR 1\n\n #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLES30)) \n #pragma target 3.0\n#else\n #pragma target 4.5\n#endif\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n #define SHADERPASS SHADERPASS_MOTION_VECTORS\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define VARYINGS_NEED_PASS\n #define _PASSMOTIONVECTOR 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _URP 1\n#define _USINGTEXCOORD1 1\n\n\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl\"\n #include_with_pragmas \"Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPass.hlsl\"\n \n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n \n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #define _WorldSpaceLightPos0 _MainLightPosition\n \n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(name) TEXTURE2D_ARRAY(name);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n \n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n \n\n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n // float4 texcoord2 : TEXCOORD5;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n half4 vertexColor : COLOR;\n // #endif\n\n #if defined(LIGHTMAP_ON)\n float2 lightmapUV : TEXCOORD8;\n #endif\n #if defined(DYNAMICLIGHTMAP_ON)\n float2 dynamicLightmapUV : TEXCOORD9;\n #endif\n #if !defined(LIGHTMAP_ON)\n float4 probeOcclusion : TEXCOORD8;\n float3 sh : TEXCOORD10;\n #endif\n\n #if defined(VARYINGS_NEED_FOG_AND_VERTEX_LIGHT)\n float4 fogFactorAndVertexLight : TEXCOORD11;\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n float4 shadowCoord : TEXCOORD12;\n #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD15;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD16;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD17;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD18;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD19;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD20;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n uint instanceID : CUSTOM_INSTANCE_ID;\n #endif\n #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))\n uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;\n #endif\n #if (defined(UNITY_STEREO_INSTANCING_ENABLED))\n uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;\n #endif\n #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)\n FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;\n #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float4 previousPositionCS : TEXCOORD21; // Contain previous transform position (in case of skinning for example)\n float4 positionCS : TEXCOORD22;\n #endif\n };\n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n CBUFFER_START(UnityPerMaterial)\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n #if defined(_PASSSHADOW)\n float3 _LightDirection;\n float3 _LightPosition;\n #endif\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #define GetWorldToViewMatrix() _ViewMatrix\n #define UNITY_MATRIX_I_V _InvViewMatrix\n #define GetViewToHClipMatrix() OptimizeProjectionMatrix(_ProjMatrix)\n #define UNITY_MATRIX_I_P _InvProjMatrix\n #define GetWorldToHClipMatrix() _ViewProjMatrix\n #define UNITY_MATRIX_I_VP _InvViewProjMatrix\n #define UNITY_MATRIX_UNJITTERED_VP _NonJitteredViewProjMatrix\n #define UNITY_MATRIX_PREV_VP _PrevViewProjMatrix\n #define UNITY_MATRIX_PREV_I_VP _PrevInvViewProjMatrix\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n // vertex shader\n VertexToPixel Vert (VertexData v)\n {\n VertexToPixel o = (VertexToPixel)0;\n\n UNITY_SETUP_INSTANCE_ID(v);\n UNITY_TRANSFER_INSTANCE_ID(v, o);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);\n\n \n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = v;\n #endif\n #if !_TESSELLATION_ON\n ChainModifyVertex(v, o, _Time);\n #endif\n\n o.texcoord0 = v.texcoord0;\n o.texcoord1 = v.texcoord1;\n // o.texcoord2 = v.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // o.texcoord3 = v.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n o.vertexColor = v.vertexColor;\n // #endif\n\n // This return the camera relative position (if enable)\n float3 positionWS = TransformObjectToWorld(v.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(v.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(v.tangent.xyz), v.tangent.w);\n \n VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);\n o.worldPos = positionWS;\n o.worldNormal = normalWS;\n o.worldTangent = tangentWS;\n\n\n // For some very odd reason, in 2021.2, we can't use Unity's defines, but have to use our own..\n #if _PASSSHADOW\n #if _CASTING_PUNCTUAL_LIGHT_SHADOW\n float3 lightDirectionWS = normalize(_LightPosition - o.worldPos);\n #else\n float3 lightDirectionWS = _LightDirection;\n #endif\n // Define shadow pass specific clip position for Universal\n o.pos = TransformWorldToHClip(ApplyShadowBias(o.worldPos, o.worldNormal, lightDirectionWS));\n #if UNITY_REVERSED_Z\n o.pos.z = min(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #else\n o.pos.z = max(o.pos.z, UNITY_NEAR_CLIP_VALUE);\n #endif\n #elif _PASSMETA\n o.pos = MetaVertexPosition(float4(v.vertex.xyz, 0), v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);\n #else\n o.pos = TransformWorldToHClip(o.worldPos);\n #endif\n\n #if _SNOWSPARKLES\n o.screenPos = ComputeScreenPos(o.pos, _ProjectionParams.x);\n #endif\n\n \n #if _PASSFORWARD || _PASSGBUFFER\n float2 uv1 = v.texcoord1.xy;\n OUTPUT_LIGHTMAP_UV(uv1, unity_LightmapST, o.lightmapUV);\n o.texcoord1.xy = uv1;\n OUTPUT_SH(o.worldNormal, o.sh);\n \n #if defined(DYNAMICLIGHTMAP_ON)\n o.dynamicLightmapUV.xy = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n #if UNITY_VERSION >= 60000009\n OUTPUT_SH(o.worldNormal, o.sh);\n #endif\n #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && UNITY_VERSION >= 60000009\n OUTPUT_SH4(vertexInput.positionWS, o.worldNormal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), o.sh, o.probeOcclusion);\n #endif\n #endif\n\n #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT\n half fogFactor = 0;\n #if defined(_FOG_FRAGMENT)\n fogFactor = ComputeFogFactor(o.pos.z);\n #endif\n #if _BAKEDLIT\n o.fogFactorAndVertexLight = half4(fogFactor, 0, 0, 0);\n #else\n half3 vertexLight = VertexLighting(o.worldPos, o.worldNormal);\n o.fogFactorAndVertexLight = half4(fogFactor, vertexLight);\n #endif\n #endif\n\n #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)\n o.shadowCoord = GetShadowCoord(vertexInput);\n #endif\n\n #if _URP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(o);\n #endif\n\n o.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n if (!forceNoMotion)\n {\n #if defined(HAVE_VFX_MODIFICATION)\n float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n const bool applyDeformation = false;\n #else\n const bool applyDeformation = true;\n #endif\n #else\n const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation\n float3 previousPositionOS = hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz;\n\n #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)\n const bool applyDeformation = true;\n #else\n const bool applyDeformation = hasDeformation;\n #endif\n #endif\n // TODO\n #if defined(FEATURES_GRAPH_VERTEX)\n if (applyDeformation)\n previousPositionOS = GetLastFrameDeformedPosition(previousMesh, currentFrameMvData, previousPositionOS);\n else\n previousPositionOS = previousMesh.positionOS;\n\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n #endif\n\n #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)\n // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes\n // Needs to be called after vertex modification has been applied otherwise it will be\n // overwritten by Compute Deform node\n ApplyPreviousFrameDeformedVertexPosition(previousMesh.vertexID, previousPositionOS);\n #endif\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n previousPositionOS -= previousMesh.precomputedVelocity;\n #endif\n o.positionCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionWS, 1.0f));\n\n #if defined(HAVE_VFX_MODIFICATION)\n #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)\n #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)\n #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.\n #endif\n o.previousPositionCS = VFXGetPreviousClipPosition(previousMesh, currentFrameMvData.vfxElementAttributes, o.positionCS);\n #else\n #if VFX_WORLD_SPACE\n //previousPositionOS is already in world space\n const float3 previousPositionWS = previousPositionOS;\n #else\n const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;\n #endif\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionWS, 1.0f));\n #endif\n #else\n o.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1)));\n #endif\n }\n #endif\n\n return o;\n }\n\n\n \n \n // Using parts of com.unity.render-pipelines.universal\\Editor\\ShaderGraph\\Includes\\MotionVectorPass.hlsl\n // com.unity.render-pipelines.universal\\ShaderLibrary\\MotionVectorsCommon.hlsl\n // com.unity.render-pipelines.universal\\Editor\\ShaderGraph\\Includes\\Varyings.hlsl\n\n float2 CalcNdcMotionVectorFromCsPositions(float4 posCS, float4 prevPosCS)\n {\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n return float2(0.0, 0.0);\n\n // Non-uniform raster needs to keep the posNDC values in float to avoid additional conversions\n // since uv remap functions use floats\n float2 posNDC = posCS.xy * rcp(posCS.w);\n float2 prevPosNDC = prevPosCS.xy * rcp(prevPosCS.w);\n\n float2 velocity;\n #if defined(SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER)\n UNITY_BRANCH if (_FOVEATED_RENDERING_NON_UNIFORM_RASTER)\n {\n // Convert velocity from NDC space (-1..1) to screen UV 0..1 space since FoveatedRendering remap needs that range.\n float2 posUV = RemapFoveatedRenderingResolve(posNDC * 0.5 + 0.5);\n float2 prevPosUV = RemapFoveatedRenderingPrevFrameLinearToNonUniform(prevPosNDC * 0.5 + 0.5);\n\n // Calculate forward velocity\n velocity = (posUV - prevPosUV);\n #if UNITY_UV_STARTS_AT_TOP\n velocity.y = -velocity.y;\n #endif\n }\n else\n #endif\n {\n // Calculate forward velocity\n velocity = (posNDC.xy - prevPosNDC.xy);\n #if UNITY_UV_STARTS_AT_TOP\n velocity.y = -velocity.y;\n #endif\n\n // Convert velocity from NDC space (-1..1) to UV 0..1 space\n // Note: It doesn't mean we don't have negative values, we store negative or positive offset in UV space.\n // Note: ((posNDC * 0.5 + 0.5) - (prevPosNDC * 0.5 + 0.5)) = (velocity * 0.5)\n velocity.xy *= 0.5;\n }\n\n return velocity;\n }\n\n float4 Frag(\n VertexToPixel input) : SV_Target\n {\n UNITY_SETUP_INSTANCE_ID(input);\n\n float4 motionVector = float4(CalcNdcMotionVectorFromCsPositions(input.positionCS, input.previousPositionCS), 0, 0);\n \n return motionVector;\n }\n\n ENDHLSL\n }\n \n\n\n\n\n\n\n\n\n\n\n \n\n }\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"},{"srpTarget":2,"UnityVersionMin":20233,"UnityVersionMax":30000,"shader":{"instanceID":0},"shaderSrc":"////////////////////////////////////////\n// Generated with Better Shaders\n//\n// Auto-generated shader code, don't hand edit!\n//\n// Unity Version: 2021.3.29f1\n// Render Pipeline: HDRP2023\n// Platform: OSXEditor\n////////////////////////////////////////\n\n\nShader \"MicroVerse/Road/RoadLit\"\n{\n Properties\n {\n \n // only here for revisioning from 2019/2020 version\n [HideInInspector]_NoiseTex(\"Noise Texture\", 2D) = \"black\" {}\n [HideInInspector]_Version(\"Version\", Int) = 0\n\n\n\t[Header(Main)]\n\t_Asphalt_Albedo(\"Albedo\", 2D) = \"white\" {}\n _AlphaThreshold(\"Alpha Threshold\", Range(0,1)) = 0.0\n\t_Asphalt_Tint(\"Tint\", Color) = (1,1,1,1) \n\t_Asphalt_NormalSAO(\"NSAO (Smoothness, NormalY, AO, NormalX)\", 2D) = \"bump\" {}\n\t_Asphalt_MaskMap(\"Mask Map\", 2D) = \"black\" {}\n\t_Asphalt_NormalStrength(\"Normal Strength\", Range(0,1)) = 1\n\t_Asphalt_Smoothness(\"Smoothness Modifier\", Range(-1,1)) = 0\n\t_Asphalt_Metallic (\"Metallic Modifier\", Range(-1,1)) = 0\n\t_AsphaltStochasticContrast(\"Asphalt Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _AsphaltStochasticScale(\"Asphalt Stochastic Scale\", Range(0,2)) = 1\n\n\t_Mask(\"LineA/LineB/WearUV/WearWorld\", 2D) = \"black\" {}\n\n\t[Header(Lines)]\n\t_LineColorA(\"Line Color A\", Color) = (1,1,1,1)\n\t_LineColorB(\"Line Color B\", Color) = (1,1,0,1)\n\t_LineEmissiveA(\"Line Emission\", Float) = 0\n\t_LineEmissiveB(\"Line Emission\", Float) = 0\n\n\t[Header(Wear Noise)]\n\t_WearNoise(\"Wear Noise Texture\", 2D) = \"black\" {}\n\t_LineWear(\"Line Wear\", Range(0,1)) = 0.5\n\t\n\t[Header(WearA)]\n\t_WearMapA(\"Normal\", 2D) = \"bump\" {}\n\t_WearA_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearA_PBR(\"Smoothness, Occlusion, Normal\", Vector) = (0, 0, 0, 1)\n\t_WearA_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(WearB)]\n\t_WearMapB(\"Normal\", 2D) = \"bump\" {}\n\t_WearB_Tint(\"Tint\", Color) = (0.5,0.5,0.5,0.5)\n\t_WearB_PBR(\"Smoothness, Occlusion, Normal, Strength\", Vector) = (0, 0, 0, 1)\n\t_WearB_NoiseParams(\"Contrast, Invert\", Vector) = (8, 0, 0, 0)\n\n\t[Header(Overlay)]\n\t_Overlay_Albedo(\"Overlay Albedo\", 2D) = \"white\" {}\n\t_Overlay_Normal(\"Overlay Normal\", 2D) = \"bump\" {}\n\t_Overlay_Mask(\"Overlay Mask\", 2D) = \"black\" {}\n\t_Overlay_VariationMask(\"Variation Mask\", 2D) = \"white\" {}\n\n\n\n _TraxAlbedo(\"Trax Albedo\", 2D) = \"white\" {}\n _TraxPackedNormal(\"Trax Packed Normal\", 2D) = \"bump\" {}\n _TraxNormalStrength(\"Normal Strength\", Range(0,2)) = 1\n _TraxDisplacementDepth(\"Trax Depression Depth\", Float) = 0.1\n _TraxDisplacementStrength(\"Trax Displacement\", Range(0,3)) = 0.2\n _TraxMipBias(\"Trax Mip Bias\", Range(0, 5)) = 3\n _TraxInterpContrast(\"Interpolation Contrast\", Range(0,1)) = 0.9\n _TraxHeightContrast(\"Height Contrast\", Range(0,1)) = 0.5\n _TraxTint(\"Tint Color\", Color) = (1,1,1,1)\n\n\n _WetnessMode(\"Wetness Mode\", Int) = 0\n _PuddleMode(\"Puddle Mode\", Int) = 0\n _RainMode(\"Rain Mode\", Int) = 0\n _RainUV(\"Rain UV\", Int) = 0\n _WetnessAmount(\"Wetness Amount\", Range(0,1)) = 0\n _Porosity(\"Porosity\", Range(0,1)) = 0.4\n _WetnessMin(\"Minimum Wetness\", Range(0,1)) = 0\n _WetnessMax(\"Maximum Wetness\", Range(0,1)) = 1\n _WetnessFalloff(\"Angle Falloff\", Range(0,1)) = 1\n _WetnessAngleMin(\"Wetness Minimum Angle\", Range(-1,1)) = -1\n _PuddleAmount(\"Puddle Amount\", Range(0,1)) = 0\n _PuddleFalloff(\"Puddle Contrast\", Range(2, 50)) = 12\n _PuddleAngleMin(\"Moss Angle Minimum\", Range(0,1)) = 0.1\n _PuddleColor(\"Puddle Color\", Color) = (0.2, 0.2, 0.2, 0.95)\n _PuddleNoiseTex(\"Noise Texture\", 2D) = \"black\" { }\n _PuddleNoiseFrequency(\"Noise Frequency\", Float) = 1\n _PuddleNoiseAmplitude(\"Noise Amplitude\", Range(0,10)) = 0.5\n _PuddleNoiseCenter(\"Noise Center\", Range(-5, 5)) = 0\n _PuddleNoiseOffset(\"Noise Offset\", Float) = 0\n _RainDropTexture(\"RainDrop Texture\", 2D) = \"white\" {}\n _RainIntensityScale(\"Intensity/Scale/MinWet\", Vector) = (1, 25, 0, 400)\n _WetnessShoreline(\"Wetness Shore Height\", Float) = -99999\n _PuddleHeightDampening(\"Height Dampening\", Range(0,1)) = 0\n [Toggle(_WETNESSEFFECTOR)] _WetnessUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_WetnessEffectorInvert(\"Invert\", Float) = 0\n [Toggle(_PUDDLEEFFECTOR)] _PuddleUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_PuddleEffectorInvert(\"Invert\", Float) = 0\n\n\n _SnowMode(\"Snow Mode\", Int) = 0\n _SnowAlbedo(\"Snow Albedo\", 2D) = \"white\" {}\n _SnowTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowNormal(\"Snow Normal\", 2D) = \"bump\" {}\n _SnowMaskMap(\"Snow Mask Map\", 2D) = \"black\" {}\n _SnowAmount(\"Snow Amount\", Range(0,1)) = 1\n _SnowAngle(\"Snow Angle Falloff\", Range(0,2)) = 1\n _SnowContrast(\"Snow Contrast\", Range(0.5, 4)) = 1.5\n _SnowVertexHeight(\"Snow Vertex Height\", Range(0,1)) = 0.0\n _SnowWorldFade(\"Snow Height Fade\", Vector) = (100, 50, 0, 0)\n _SnowTraxAlbedo(\"Snow Trax Albedo\", 2D) = \"white\" {}\n _SnowTraxTint(\"Snow Trax Albedo\", Color) = (1,1,1,1)\n _SnowTraxNormal(\"Snow Trax Normal\", 2D) = \"bump\" {}\n _SnowTraxMaskMap(\"Snow Trax Mask Map\", 2D) = \"black\" {}\n _SnowNoiseFreq(\"Snow Noise Frequency\", Float) = 1\n _SnowNoiseAmp(\"Snow Noise Amplitude\", Float) = 1\n _SnowNoiseOffset(\"Snow Noise Offset\", Float) = 0\n _SnowStochasticContrast(\"Snow Stochastic Contrast\", Range(0.01, 0.99)) = 0.7\n _SnowStochasticScale(\"Snow Stochastic Scale\", Range(0,2)) = 1\n\n _SnowFresnelColor(\"Fresnel Color\", Color) = (0,0,0,0)\n\t_SnowFresnelBSP(\"Fresnel Bias Scale Power\", Vector) = (0,9,3,0)\n\n _SnowSparkleNoise(\"Sparkle Noise\", 2D) = \"black\" {}\n\t_SnowSparkleTCI(\"Sparkle Tiling/Cutoff/Intensity/Emission\", Vector) = (1, 0.7, 1, 0)\n\n [Toggle(_SNOWEFFECTOR)] _SnowUseEffector(\"Use Effector\", Float) = 0\n [MaterialToggle]_SnowEffectorInvert(\"Invert\", Float) = 0\n\n\n\n [HideInInspector]_RenderQueueType(\"Float\", Float) = 1\n [HideInInspector][ToggleUI]_AddPrecomputedVelocity(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_DepthOffsetEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentWritingMotionVec(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaCutoffEnable(\"Boolean\", Float) = 0\n [HideInInspector]_TransparentSortPriority(\"_TransparentSortPriority\", Float) = 0\n [HideInInspector][ToggleUI]_UseShadowThreshold(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPrepassEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_TransparentDepthPostpassEnable(\"Boolean\", Float) = 0\n [HideInInspector]_SurfaceType(\"Float\", Float) = 0\n [HideInInspector]_BlendMode(\"Float\", Float) = 0\n [HideInInspector]_SrcBlend(\"Float\", Float) = 1\n [HideInInspector]_DstBlend(\"Float\", Float) = 0\n [HideInInspector]_AlphaSrcBlend(\"Float\", Float) = 1\n [HideInInspector]_AlphaDstBlend(\"Float\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMask(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_AlphaToMaskInspectorValue(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ZWrite(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_TransparentZWrite(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableFogOnTransparent(\"Boolean\", Float) = 1\n [HideInInspector]_ZTestDepthEqualForOpaque(\"Float\", Int) = 4\n [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)]_ZTestTransparent(\"Float\", Float) = 4\n [HideInInspector][ToggleUI]_TransparentBackfaceEnable(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_RequireSplitLighting(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_ReceivesSSR(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_ReceivesSSRTransparent(\"Boolean\", Float) = 0\n [HideInInspector][ToggleUI]_EnableBlendModePreserveSpecularLighting(\"Boolean\", Float) = 1\n [HideInInspector][ToggleUI]_SupportDecals(\"Boolean\", Float) = 1\n [HideInInspector]_StencilRef(\"Float\", Int) = 0\n [HideInInspector]_StencilWriteMask(\"Float\", Int) = 6\n [HideInInspector]_StencilRefDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilWriteMaskDepth(\"Float\", Int) = 8\n [HideInInspector]_StencilRefMV(\"Float\", Int) = 40\n [HideInInspector]_StencilWriteMaskMV(\"Float\", Int) = 40\n [HideInInspector]_StencilRefDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskDistortionVec(\"Float\", Int) = 4\n [HideInInspector]_StencilWriteMaskGBuffer(\"Float\", Int) = 14\n [HideInInspector]_StencilRefGBuffer(\"Float\", Int) = 10\n [HideInInspector]_ZTestGBuffer(\"Float\", Int) = 4\n [HideInInspector][ToggleUI]_RayTracing(\"Boolean\", Float) = 0\n [HideInInspector][Enum(None, 0, Box, 1, Sphere, 2, Thin, 3)]_RefractionModel(\"Float\", Float) = 0\n [HideInInspector][NoScaleOffset]unity_Lightmaps(\"unity_Lightmaps\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_LightmapsInd(\"unity_LightmapsInd\", 2DArray) = \"\" {}\n [HideInInspector][NoScaleOffset]unity_ShadowMasks(\"unity_ShadowMasks\", 2DArray) = \"\" {}\n }\n SubShader\n {\n Tags { \"RenderPipeline\" = \"HDRenderPipeline\" \"RenderType\" = \"HDLitShader\" \"Queue\" = \"Geometry+225\" }\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"Forward\"\n Tags { \"LightMode\" = \"Forward\" }\n\n \n \n Stencil\n {\n WriteMask [_StencilWriteMask]\n Ref [_StencilRef]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n \n ColorMask [_ColorMaskTransparentVel] 1\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n\n #pragma target 4.5\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n\n\n #pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n #pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC _TRANSPARENT_REFRACTIVE_SORT\n #pragma shader_feature_local_fragment _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_fragment _ _DISABLE_SSR\n #pragma shader_feature_local_fragment _ _DISABLE_SSR_TRANSPARENT\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n\n #pragma multi_compile _ DEBUG_DISPLAY\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n #pragma multi_compile_fragment PUNCTUAL_SHADOW_LOW PUNCTUAL_SHADOW_MEDIUM PUNCTUAL_SHADOW_HIGH\n #pragma multi_compile_fragment DIRECTIONAL_SHADOW_LOW DIRECTIONAL_SHADOW_MEDIUM DIRECTIONAL_SHADOW_HIGH\n #pragma multi_compile_fragment AREA_SHADOW_MEDIUM AREA_SHADOW_HIGH\n #pragma multi_compile_fragment SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON\n #pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n #pragma multi_compile _ USE_LEGACY_LIGHTMAPS\n \n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_FORWARD\n #define SUPPORT_BLENDMODE_PRESERVE_SPECULAR_LIGHTING\n #define HAS_LIGHTLOOP\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSFORWARD 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n #define VT_BUFFER_TARGET SV_Target1\n #define EXTRA_BUFFER_TARGET SV_Target2\n #else\n #define EXTRA_BUFFER_TARGET SV_Target1\n #endif\n\n\n\n\n void Frag(VertexToPixel v2p,\n #ifdef OUTPUT_SPLIT_LIGHTING\n out float4 outColor : SV_Target0, // outSpecularLighting\n #ifdef UNITY_VIRTUAL_TEXTURING\n out float4 outVTFeedback : VT_BUFFER_TARGET,\n #endif\n out float4 outDiffuseLighting : EXTRA_BUFFER_TARGET,\n OUTPUT_SSSBUFFER(outSSSBuffer)\n #else\n out float4 outColor : SV_Target0\n #ifdef UNITY_VIRTUAL_TEXTURING\n ,out float4 outVTFeedback : VT_BUFFER_TARGET\n #endif\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n , out float4 outMotionVec : EXTRA_BUFFER_TARGET\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif // OUTPUT_SPLIT_LIGHTING\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n // Init outMotionVector here to solve compiler warning (potentially unitialized variable)\n // It is init to the value of forceNoMotion (with 2.0)\n outMotionVec = float4(2.0, 0.0, 0.0, 0.0);\n #endif\n\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // We need to readapt the SS position as our screen space positions are for a low res buffer, but we try to access a full res buffer.\n input.positionSS.xy = _OffScreenRendering > 0 ? (input.positionSS.xy * _OffScreenDownsampleFactor) : input.positionSS.xy;\n\n uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n \n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n\n PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);\n\n outColor = float4(0.0, 0.0, 0.0, 0.0);\n\n // We need to skip lighting when doing debug pass because the debug pass is done before lighting so some buffers may not be properly initialized potentially causing crashes on PS4.\n\n #ifdef DEBUG_DISPLAY\n // Init in debug display mode to quiet warning\n #ifdef OUTPUT_SPLIT_LIGHTING\n outDiffuseLighting = 0;\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #endif\n\n \n\n // Same code in ShaderPassForwardUnlit.shader\n // Reminder: _DebugViewMaterialArray[i]\n // i==0 -> the size used in the buffer\n // i>0 -> the index used (0 value means nothing)\n // The index stored in this buffer could either be\n // - a gBufferIndex (always stored in _DebugViewMaterialArray[1] as only one supported)\n // - a property index which is different for each kind of material even if reflecting the same thing (see MaterialSharedProperty)\n bool viewMaterial = false;\n int bufferSize = _DebugViewMaterialArray[0].x;\n if (bufferSize != 0)\n {\n bool needLinearToSRGB = false;\n float3 result = float3(1.0, 0.0, 1.0);\n\n // Loop through the whole buffer\n // Works because GetSurfaceDataDebug will do nothing if the index is not a known one\n for (int index = 1; index <= bufferSize; index++)\n {\n int indexMaterialProperty = _DebugViewMaterialArray[index].x;\n\n // skip if not really in use\n if (indexMaterialProperty != 0)\n {\n viewMaterial = true;\n\n GetPropertiesDataDebug(indexMaterialProperty, result, needLinearToSRGB);\n GetVaryingsDataDebug(indexMaterialProperty, input, result, needLinearToSRGB);\n GetBuiltinDataDebug(indexMaterialProperty, builtinData, posInput, result, needLinearToSRGB);\n GetSurfaceDataDebug(indexMaterialProperty, surfaceData, result, needLinearToSRGB);\n GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB);\n }\n }\n\n // TEMP!\n // For now, the final blit in the backbuffer performs an sRGB write\n // So in the meantime we apply the inverse transform to linear data to compensate.\n if (!needLinearToSRGB)\n result = SRGBToLinear(max(0, result));\n\n outColor = float4(result, 1.0);\n }\n\n if (!viewMaterial)\n {\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR || _DebugFullScreenMode == FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR)\n {\n float3 result = float3(0.0, 0.0, 0.0);\n\n GetPBRValidatorDebug(surfaceData, result);\n\n outColor = float4(result, 1.0f);\n }\n else if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)\n {\n float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);\n outColor = result;\n }\n else\n #endif\n {\n #ifdef _SURFACE_TYPE_TRANSPARENT\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;\n #else\n uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;\n #endif\n\n LightLoopOutput lightLoopOutput;\n LightLoop(V, posInput, preLightData, bsdfData, builtinData, featureFlags, lightLoopOutput);\n\n float3 diffuseLighting = lightLoopOutput.diffuseLighting;\n float3 specularLighting = lightLoopOutput.specularLighting;\n\n diffuseLighting *= GetCurrentExposureMultiplier();\n specularLighting *= GetCurrentExposureMultiplier();\n\n #ifdef OUTPUT_SPLIT_LIGHTING\n if (_EnableSubsurfaceScattering != 0 && ShouldOutputSplitLighting(bsdfData))\n {\n outColor = float4(specularLighting, 1.0);\n outDiffuseLighting = float4(TagLightingForSSS(diffuseLighting), 1.0);\n }\n else\n {\n outColor = float4(diffuseLighting + specularLighting, 1.0);\n outDiffuseLighting = 0;\n }\n ENCODE_INTO_SSSBUFFER(surfaceData, posInput.positionSS, outSSSBuffer);\n #else\n outColor = ApplyBlendMode(diffuseLighting, specularLighting, builtinData.opacity);\n outColor = EvaluateAtmosphericScattering(posInput, V, outColor);\n #endif\n\n ChainFinalColorForward(l, d, outColor);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);\n // outMotionVec is already initialize at the value of forceNoMotion (see above)\n if (!forceNoMotion)\n {\n float2 motionVec = CalculateMotionVector(v2p.motionVectorCS, v2p.previousPositionCS);\n EncodeMotionVector(motionVec * 0.5, outMotionVec);\n outMotionVec.zw = 1.0;\n }\n #endif\n }\n\n #ifdef DEBUG_DISPLAY\n }\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n outVTFeedback = builtinData.vtPackedFeedback;\n #endif\n }\n\n ENDHLSL\n }\n Pass\n {\n // based on HDLitPass.template\n Name \"GBuffer\"\n Tags { \"LightMode\" = \"GBuffer\" }\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZTest [_ZTestGBuffer]\n Stencil\n {\n WriteMask [_StencilWriteMaskGBuffer]\n Ref [_StencilRefGBuffer]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n\n #pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_fragment _ _DISABLE_SSR\n\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n #pragma multi_compile_fragment _ RENDERING_LAYERS\n #pragma multi_compile _ DEBUG_DISPLAY\n #pragma multi_compile _ LIGHTMAP_ON\n #pragma multi_compile _ DIRLIGHTMAP_COMBINED\n #pragma multi_compile_fragment _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2\n #pragma multi_compile _ DYNAMICLIGHTMAP_ON\n #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK\n #pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT\n #pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT\n #pragma multi_compile _ USE_LEGACY_LIGHTMAPS\n\n\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_GBUFFER\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define _PASSGBUFFER 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n\n\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n void Frag( VertexToPixel v2f,\n OUTPUT_GBUFFER(outGBuffer)\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n \n ENCODE_INTO_GBUFFER(surfaceData, builtinData, posInput.positionSS, outGBuffer);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n }\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"ShadowCaster\"\n Tags { \"LightMode\" = \"ShadowCaster\" }\n\n \n\n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n ZWrite On\n ColorMask 0\n ZClip [_ZClip]\n \n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n //#pragma multi_compile_local _ _ALPHATEST_ON\n\n\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_SHADOWS\n #define _PASSSHADOW 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n //-------------------------------------------------------------------------------------\n // Defines\n //-------------------------------------------------------------------------------------\n \n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n \n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n #endif\n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n DecalPrepassData decalPrepassData;\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n #endif\n decalPrepassData.renderingLayerMask = GetMeshRenderingLayerMask();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n\n\n }\n\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"DepthOnly\"\n Tags { \"LightMode\" = \"DepthOnly\" }\n \n //-------------------------------------------------------------------------------------\n // Render Modes (Blend, Cull, ZTest, Stencil, etc)\n //-------------------------------------------------------------------------------------\n \n Cull Back\n \n \n ZWrite On\n \n \n // Stencil setup\n Stencil\n {\n WriteMask [_StencilWriteMaskDepth]\n Ref [_StencilRefDepth]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n AlphaToMask [_AlphaCutoffEnable]\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n //#pragma enable_d3d11_debug_symbols\n \n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n #pragma multi_compile_fragment _ WRITE_DECAL_BUFFER WRITE_RENDERING_LAYER\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n\n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n \n #define _PASSDEPTH 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n #if defined(WRITE_NORMAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target2\n #elif defined(WRITE_NORMAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n #define SV_TARGET_DECAL SV_Target1\n #else\n #define SV_TARGET_DECAL SV_Target0\n #endif\n\n\n void Frag( VertexToPixel v2p\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n\n #if defined(_DEPTHOFFSET_ON) && !defined(SCENEPICKINGPASS)\n , out float outputDepth : DEPTH_OFFSET_SEMANTIC\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2p);\n FragInputs input = BuildFragInputs(v2p);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2p, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // to prevent stripping\n surfaceData.normalWS *= saturate(l.Albedo.r + 9999);\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = unity_SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n DecalPrepassData decalPrepassData;\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n #endif\n decalPrepassData.renderingLayerMask = GetMeshRenderingLayerMask();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n }\n\n\n\n ENDHLSL\n }\n\n\n \n Pass\n {\n // based on HDLitPass.template\n Name \"META\"\n Tags { \"LightMode\" = \"META\" }\n \n Cull Off\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n #pragma multi_compile_instancing\n\n #pragma shader_feature _ EDITOR_VISUALIZATION\n #pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local_fragment _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_raytracing _ _DISABLE_DECALS\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_LIGHT_TRANSPORT\n #define RAYTRACING_SHADER_GRAPH_HIGH\n #define REQUIRE_DEPTH_TEXTURE\n #define _PASSMETA 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n\n \n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n float4 Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n ) : SV_Target\n {\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n // no debug apply during light transport pass\n\n BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);\n LightTransportData lightTransportData = GetLightTransportData(surfaceData, builtinData, bsdfData);\n\n // This shader is call two times. Once for getting emissiveColor, the other time to get diffuseColor\n // We use unity_MetaFragmentControl to make the distinction.\n float4 res = float4(0.0, 0.0, 0.0, 1.0);\n\n if (unity_MetaFragmentControl.x)\n {\n // Apply diffuseColor Boost from LightmapSettings.\n // put abs here to silent a warning, no cost, no impact as color is assume to be positive.\n res.rgb = clamp(pow(abs(lightTransportData.diffuseColor), saturate(unity_OneOverOutputBoost)), 0, unity_MaxOutputValue);\n }\n\n if (unity_MetaFragmentControl.y)\n {\n // emissive use HDR format\n res.rgb = lightTransportData.emissiveColor;\n }\n\n return res;\n }\n\n\n\n ENDHLSL\n }\n \n Pass\n {\n // based on HDLitPass.template\n Name \"SceneSelectionPass\"\n Tags { \"LightMode\" = \"SceneSelectionPass\" }\n \n Cull Off\n ColorMask 0\n\n \n\n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n \n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_raytracing _ _DISABLE_DECALS\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n //-------------------------------------------------------------------------------------\n // Variant Definitions (active field translations to HDRP defines)\n //-------------------------------------------------------------------------------------\n // #define _MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1\n // #define _MATERIAL_FEATURE_TRANSMISSION 1\n // #define _MATERIAL_FEATURE_ANISOTROPY 1\n // #define _MATERIAL_FEATURE_IRIDESCENCE 1\n // #define _MATERIAL_FEATURE_SPECULAR_COLOR 1\n #define _ENABLE_FOG_ON_TRANSPARENT 1\n // #define _AMBIENT_OCCLUSION 1\n // #define _SPECULAR_OCCLUSION_FROM_AO 1\n // #define _SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL 1\n // #define _SPECULAR_OCCLUSION_CUSTOM 1\n // #define _ENERGY_CONSERVING_SPECULAR 1\n // #define _ENABLE_GEOMETRIC_SPECULAR_AA 1\n // #define _HAS_REFRACTION 1\n // #define _REFRACTION_PLANE 1\n // #define _REFRACTION_SPHERE 1\n // #define _DISABLE_DECALS 1\n // #define _DISABLE_SSR 1\n // #define _ADD_PRECOMPUTED_VELOCITY\n // #define _WRITE_TRANSPARENT_MOTION_VECTOR 1\n // #define _DEPTHOFFSET_ON 1\n // #define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define SCENESELECTIONPASS\n #define _PASSSCENESELECT 1\n\n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n \n \n\n \n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n \n\n \n void Frag( VertexToPixel IN\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #ifdef WRITE_MSAA_DEPTH\n , out float1 depthColor : SV_Target1\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When only WRITE_MSAA_DEPTH is define and not WRITE_NORMAL_BUFFER it mean we are Unlit and only need depth, but we still have normal buffer binded\n , out float4 outNormalBuffer : SV_Target0\n , out float1 depthColor : SV_Target1\n #elif defined(SCENESELECTIONPASS)\n , out float4 outColor : SV_Target0\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);\n FragInputs input = BuildFragInputs(IN);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(IN, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = l.outputDepth;\n #endif\n\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), posInput.positionSS, outNormalBuffer);\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #endif\n #elif defined(WRITE_MSAA_DEPTH) // When we are MSAA depth only without normal buffer\n // Due to the binding order of these two render targets, we need to have them both declared\n outNormalBuffer = float4(0.0, 0.0, 0.0, 1.0);\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n #elif defined(SCENESELECTIONPASS)\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"ScenePickingPass\"\n Tags\n {\n \"LightMode\" = \"Picking\"\n }\n \n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma editor_sync_compilation\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ DOTS_INSTANCING_ON\n\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_raytracing _ _DISABLE_DECALS\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n #define SHADERPASS SHADERPASS_DEPTH_ONLY\n #define SCENEPICKINGPASS\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n void Frag( VertexToPixel v2f\n #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS)\n , out float4 outColor : SV_Target0\n #else\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target1\n #endif\n #else\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_Target0\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)\n , out float4 outDecalBuffer : SV_TARGET_DECAL\n #endif\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n // input.positionSS is SV_Position\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n\n \n #ifdef SCENESELECTIONPASS\n // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly\n outColor = float4(_ObjectId, _PassValue, 1.0, 1.0);\n #elif defined(SCENEPICKINGPASS)\n outColor = _SelectionID;\n #else\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2p.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif // alphatomask\n #endif // msaa_depth\n \n\n #if defined(WRITE_NORMAL_BUFFER)\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n DecalPrepassData decalPrepassData;\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n #endif\n decalPrepassData.renderingLayerMask = GetMeshRenderingLayerMask();\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n #endif\n #endif\n\n\n }\n\n ENDHLSL\n }\n\n Pass\n {\n Name \"MotionVectors\"\n Tags\n {\n \"LightMode\" = \"MotionVectors\"\n }\n \n // Render State\n Cull Back\n ZWrite On\n Stencil\n {\n WriteMask [_StencilWriteMaskMV]\n Ref [_StencilRefMV]\n CompFront Always\n PassFront Replace\n CompBack Always\n PassBack Replace\n }\n\n \n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile_instancing\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma instancing_options renderinglayer\n #pragma multi_compile _ LOD_FADE_CROSSFADE\n\n #pragma multi_compile _ WRITE_MSAA_DEPTH\n //#pragma shader_feature _ _SURFACE_TYPE_TRANSPARENT\n //#pragma shader_feature_local _BLENDMODE_OFF _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY\n //#pragma shader_feature_local _ _ADD_PRECOMPUTED_VELOCITY\n //#pragma shader_feature_local _ _TRANSPARENT_WRITES_MOTION_VEC\n //#pragma shader_feature_local _ _ENABLE_FOG_ON_TRANSPARENT\n #pragma multi_compile _ WRITE_NORMAL_BUFFER\n //#pragma shader_feature_local _ _DISABLE_DECALS\n //#pragma shader_feature_local _ _DISABLE_SSR\n //#pragma shader_feature_local _ _DISABLE_SSR_TRANSPARENT\n #pragma multi_compile _ WRITE_DECAL_BUFFER\n //#pragma shader_feature_local _REFRACTION_OFF _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n \n\n #define SHADERPASS SHADERPASS_MOTION_VECTORS\n #define RAYTRACING_SHADER_GRAPH_DEFAULT\n #define VARYINGS_NEED_PASS\n #define _PASSMOTIONVECTOR 1\n\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#if defined(WRITE_DECAL_BUFFER) && defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target3\n#elif defined(WRITE_DECAL_BUFFER) || defined(WRITE_MSAA_DEPTH)\n#define SV_TARGET_NORMAL SV_Target2\n#else\n#define SV_TARGET_NORMAL SV_Target1\n#endif\n\n// Caution: Motion vector pass is different from Depth prepass, it render normal buffer last instead of decal buffer last\n// and thus, we force a write of 0 if _DISABLE_DECALS so we always write in the decal buffer.\n// This is required as we can't make distinction between deferred (write normal buffer) and forward (write normal buffer)\n// in the context of the motion vector pass. The cost is acceptable as it is only do object with motion vector (usualy skin object)\n// that most of the time use Forward Material (so are already writing motion vector data).\n// So note that here unlike for depth prepass we don't check && !defined(_DISABLE_DECALS)\nvoid Frag( VertexToPixel v2f\n #ifdef WRITE_MSAA_DEPTH\n // We need the depth color as SV_Target0 for alpha to coverage\n , out float4 depthColor : SV_Target0\n , out float4 outMotionVector : SV_Target1\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target2\n #endif\n #else\n // When no MSAA, the motion vector is always the first buffer\n , out float4 outMotionVector : SV_Target0\n #ifdef WRITE_DECAL_BUFFER\n , out float4 outDecalBuffer : SV_Target1\n #endif\n #endif\n\n // Decal buffer must be last as it is bind but we can optionally write into it (based on _DISABLE_DECALS)\n #ifdef WRITE_NORMAL_BUFFER\n , out float4 outNormalBuffer : SV_TARGET_NORMAL\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n , out float outputDepth : SV_Depth\n #endif\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n\n FragInputs input = BuildFragInputs(v2f);\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS);\n\n float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);\n\n\n SurfaceData surfaceData;\n BuiltinData builtinData;\n Surface l;\n ShaderData d;\n GetSurfaceAndBuiltinData(v2f, input, V, posInput, surfaceData, builtinData, l, d\n #if NEED_FACING\n , facing\n #endif\n );\n\n #ifdef _DEPTHOFFSET_ON\n v2f.motionVectorCS.w += builtinData.depthOffset;\n v2f.previousPositionCS.w += builtinData.depthOffset;\n #endif\n\n // TODO: How to allow overriden motion vector from GetSurfaceAndBuiltinData ?\n float2 motionVector = CalculateMotionVector(v2f.motionVectorCS, v2f.previousPositionCS);\n\n // Convert from Clip space (-1..1) to NDC 0..1 space.\n // Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space.\n // Note: ((positionCS * 0.5 + 0.5) - (v2f.previousPositionCS * 0.5 + 0.5)) = (motionVector * 0.5)\n EncodeMotionVector(motionVector * 0.5, outMotionVector);\n\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n\n // Setting the motionVector to a value more than 2 set as a flag for \"force no motion\". This is valid because, given that the velocities are in NDC,\n // a value of >1 can never happen naturally, unless explicitely set. \n if (forceNoMotion)\n outMotionVector = float4(2.0, 0.0, 0.0, 0.0);\n\n // Depth and Alpha to coverage\n #ifdef WRITE_MSAA_DEPTH\n // In case we are rendering in MSAA, reading the an MSAA depth buffer is way too expensive. To avoid that, we export the depth to a color buffer\n depthColor = v2f.pos.z;\n\n #ifdef _ALPHATOMASK_ON\n // Alpha channel is used for alpha to coverage\n depthColor.a = SharpenAlpha(builtinData.opacity, builtinData.alphaClipTreshold);\n #endif\n #endif\n\n // Normal Buffer Processing\n #ifdef WRITE_NORMAL_BUFFER\n EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surfaceData), outNormalBuffer);\n #endif\n\n #if defined(WRITE_DECAL_BUFFER)\n DecalPrepassData decalPrepassData;\n // Force a write in decal buffer even if decal is disab. This is a neutral value which have no impact for later pass\n #ifdef _DISABLE_DECALS\n ZERO_INITIALIZE(DecalPrepassData, decalPrepassData);\n #else\n // We don't have the right to access SurfaceData in a shaderpass.\n // However it would be painful to have to add a function like ConvertSurfaceDataToDecalPrepassData() to every Material to return geomNormalWS anyway\n // Here we will put the constrain that any Material requiring to support Decal, will need to have geomNormalWS as member of surfaceData (and we already require normalWS anyway)\n decalPrepassData.geomNormalWS = surfaceData.geomNormalWS;\n decalPrepassData.renderingLayerMask = GetMeshRenderingLayerMask();\n #endif\n EncodeIntoDecalPrepassBuffer(decalPrepassData, outDecalBuffer);\n outDecalBuffer.w = (GetMeshRenderingLayerMask() & 0x000000FF) / 255.0;\n #endif\n\n #ifdef _DEPTHOFFSET_ON\n outputDepth = posInput.deviceDepth;\n #endif\n }\n\n ENDHLSL\n }\n\n \n Pass\n {\n Name \"FullScreenDebug\"\n Tags\n {\n \"LightMode\" = \"FullScreenDebug\"\n }\n \n // Render State\n Cull Back\n ZTest LEqual\n ZWrite Off\n \n //-------------------------------------------------------------------------------------\n // End Render Modes\n //-------------------------------------------------------------------------------------\n \n HLSLPROGRAM\n \n #pragma target 4.5\n #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch\n #pragma multi_compile _ DOTS_INSTANCING_ON\n #pragma multi_compile_instancing\n #pragma instancing_options renderinglayer\n\n\n #pragma shader_feature_local _ _DOUBLESIDED_ON\n #pragma shader_feature_local_fragment _ _DISABLE_DECALS\n #pragma shader_feature_local_raytracing _ _DISABLE_DECALS\n #pragma shader_feature_local _ _REFRACTION_PLANE _REFRACTION_SPHERE _REFRACTION_THIN\n \n\n #define SHADERPASS SHADERPASS_FULL_SCREEN_DEBUG\n #define _PASSFULLSCREENDEBUG 1\n \n \n\n\n\n\t#pragma shader_feature_local _ _WEAR_A\n\t#pragma shader_feature_local _ _WEAR_B\n\n\t#pragma shader_feature_local _ _PACKEDFAST\n\t#pragma shader_feature_local _ _ASPHALTSTOCHASTIC\n\t#pragma shader_feature_local _ _ASPHALT_WORLDTRIPLANAR\n\n\t#pragma shader_feature_local _ _OVERLAY\n\n\t#pragma shader_feature_local _ _ALPHACUT\n\n\t#define __ROADSHADER__ 1\n\t#define _ROADWEAR 1\n\n\n\n #pragma shader_feature_local _ _TRAX_ON\n\n\n #pragma shader_feature_local _ _WETNESS\n #pragma shader_feature_local _ _PUDDLES\n #pragma shader_feature_local _ _PUDDLENOISE\n #pragma shader_feature_local _ _PUDDLENOISEWORLD _PUDDLENOISELOCAL\n #pragma shader_feature_local _ _PUDDLENOISEHQ _PUDDLENOISETEXTURE _PUDDLENOISEWORLEY\n #pragma shader_feature_local _ _PUDDLEEFFECTOR\n #pragma shader_feature_local _ _WETNESSEFFECTOR\n #pragma shader_feature_local _ _RAINDROPS\n\n\n #pragma shader_feature_local _ _SNOW\n #pragma shader_feature_local _ _SNOWMASKMAP\n #pragma shader_feature_local _ _SNOWNOISE\n #pragma shader_feature_local _ _SNOWSTOCHASTIC\n #pragma shader_feature_local _ _SNOWFRESNEL _SNOWFRESNELNORMAL\n #pragma shader_feature_local _ _SNOWSPARKLES\n #pragma shader_feature_local _ _SNOWEFFECTOR\n\n\n #define _HDRP 1\n#define _USINGTEXCOORD1 1\n\n\n #pragma vertex Vert\n #pragma fragment Frag\n\n // useful conversion functions to make surface shader code just work\n\n #define UNITY_DECLARE_TEX2D(name) TEXTURE2D(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2D_NOSAMPLER(name) TEXTURE2D(name);\n #define UNITY_DECLARE_TEX2DARRAY(name) TEXTURE2D_ARRAY(name); SAMPLER(sampler##name);\n #define UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(tex) TEXTURE2D_ARRAY(tex);\n\n #define UNITY_SAMPLE_TEX2DARRAY(tex,coord) SAMPLE_TEXTURE2D_ARRAY(tex, sampler##tex, coord.xy, coord.z)\n #define UNITY_SAMPLE_TEX2DARRAY_LOD(tex,coord,lod) SAMPLE_TEXTURE2D_ARRAY_LOD(tex, sampler##tex, coord.xy, coord.z, lod)\n #define UNITY_SAMPLE_TEX2D(tex, coord) SAMPLE_TEXTURE2D(tex, sampler##tex, coord)\n #define UNITY_SAMPLE_TEX2D_SAMPLER(tex, samp, coord) SAMPLE_TEXTURE2D(tex, sampler##samp, coord)\n\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) SAMPLE_TEXTURE2D_LOD(tex, sampler_##tex, coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) SAMPLE_TEXTURE2D_LOD (tex, sampler##samplertex,coord, lod)\n\n #if defined(UNITY_COMPILER_HLSL)\n #define UNITY_INITIALIZE_OUTPUT(type,name) name = (type)0;\n #else\n #define UNITY_INITIALIZE_OUTPUT(type,name)\n #endif\n\n #define sampler2D_float sampler2D\n #define sampler2D_half sampler2D\n\n #undef WorldNormalVector\n #define WorldNormalVector(data, normal) mul(normal, data.TBNMatrix)\n\n #define UnityObjectToWorldNormal(normal) mul(GetObjectToWorldMatrix(), normal)\n\n #ifndef SHADER_STAGE_FRAGMENT\n #if !defined(SHADOW_ULTRA_LOW) && !defined(SHADOW_LOW) && !defined(SHADOW_MEDIUM) && !defined(SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define SHADOW_MEDIUM\n #endif\n #if !defined(AREA_SHADOW_LOW) && !defined(AREA_SHADOW_MEDIUM) && !defined(AREA_SHADOW_HIGH) // low come from volumetricLighting.compute\n #define AREA_SHADOW_MEDIUM\n #endif\n #if !defined(PUNCTUAL_SHADOW_ULTRA_LOW) && !defined(PUNCTUAL_SHADOW_LOW) && !defined(PUNCTUAL_SHADOW_MEDIUM) && !defined(PUNCTUAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define PUNCTUAL_SHADOW_MEDIUM\n #endif\n #if !defined(DIRECTIONAL_SHADOW_ULTRA_LOW) && !defined(DIRECTIONAL_SHADOW_LOW) && !defined(DIRECTIONAL_SHADOW_MEDIUM) && !defined(DIRECTIONAL_SHADOW_HIGH) // ultra low come from volumetricLighting.compute\n #define DIRECTIONAL_SHADOW_MEDIUM\n #endif\n #endif\n \n\n\n// HDRP Adapter stuff\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl\"\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/GeometricTools.hlsl\" // Required by Tessellation.hlsl\n \t#include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Tessellation.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPass.cs.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl\" // Required to be include before we include properties as it define DECLARE_STACK_CB\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl\" // Required before including properties as it defines UNITY_TEXTURE_STREAMING_DEBUG_VARS\n // Always include Shader Graph version\n // Always include last to avoid double macros\n #include \"Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl\" // Need to be here for Gradient struct definition\n\n\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl\"\n \n \n\n #ifdef RAYTRACING_SHADER_GRAPH_DEFAULT \n #define RAYTRACING_SHADER_GRAPH_HIGH\n #endif\n \n #ifdef RAYTRACING_SHADER_GRAPH_RAYTRACED\n #define RAYTRACING_SHADER_GRAPH_LOW\n #endif\n // end\n \n\n\n\n // If we use subsurface scattering, enable output split lighting (for forward pass)\n #if defined(_MATERIAL_FEATURE_SUBSURFACE_SCATTERING) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define OUTPUT_SPLIT_LIGHTING\n #endif\n\n #define HAVE_RECURSIVE_RENDERING\n\n #if SHADERPASS == SHADERPASS_TRANSPARENT_DEPTH_PREPASS\n #if !defined(_DISABLE_SSR_TRANSPARENT) && !defined(SHADER_UNLIT)\n #define WRITE_NORMAL_BUFFER\n #endif\n #endif\n\n #ifndef DEBUG_DISPLAY\n // In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)\n // Don't do it with debug display mode as it is possible there is no depth prepass in this case\n #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(_ALPHATEST)\n #if SHADERPASS == SHADERPASS_FORWARD\n #define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST\n #elif SHADERPASS == SHADERPASS_GBUFFER\n #define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST\n #endif\n #endif\n #endif\n\n // Define _DEFERRED_CAPABLE_MATERIAL for shader capable to run in deferred pass\n #if defined(SHADER_LIT) && !defined(_SURFACE_TYPE_TRANSPARENT)\n #define _DEFERRED_CAPABLE_MATERIAL\n #endif\n \n // Translate transparent motion vector define\n #if defined(_TRANSPARENT_WRITES_MOTION_VEC) && defined(_SURFACE_TYPE_TRANSPARENT)\n #define _WRITE_TRANSPARENT_MOTION_VECTOR\n #endif\n\n\n\n\n CBUFFER_START(UnityPerMaterial)\n float _UseShadowThreshold;\n float4 _DoubleSidedConstants;\n float _BlendMode;\n float _EnableBlendModePreserveSpecularLighting;\n float _RayTracing;\n float _RefractionModel;\n\n \n\n\n\t\n\thalf4 _Asphalt_Tint;\n\thalf _Asphalt_Metallic;\n\thalf _Asphalt_Smoothness;\n\tfloat4 _Asphalt_Albedo_ST;\n\thalf _AlphaThreshold;\n\thalf _Asphalt_NormalStrength;\n\thalf _AsphaltStochasticScale;\n\thalf _AsphaltStochasticContrast;\n\n\thalf4 _WearA_Tint;\n\thalf4 _WearA_PBR;\n\tfloat4 _WearMapA_ST;\n\thalf4 _WearA_NoiseParams;\n\t\n\n\thalf4 _WearB_Tint;\n\thalf4 _WearB_PBR;\n\tfloat4 _WearMapB_ST;\n\thalf4 _WearB_NoiseParams;\n\n\tfloat4 _WearNoise_ST;\n\n\thalf4 _LineColorA;\n\thalf4 _LineColorB;\n\thalf _LineEmissiveA;\n\thalf _LineEmissiveB;\n\thalf _LineWear;\n\n\tfloat4 _Mask_TexelSize;\n\n\tfloat4 _Overlay_Albedo_ST;\n\tfloat4 _Overlay_VariationMask_ST;\n\n\n\n //#if _TRAX_ON\n half _TraxDisplacementDepth;\n half _TraxDisplacementStrength;\n half _TraxMipBias;\n half _TraxNormalStrength;\n float4 _TraxAlbedo_ST;\n half _TraxInterpContrast;\n half _TraxHeightContrast;\n half3 _TraxTint;\n //#endif\n\n\n\n //#if _WETNESS || _PUDDLES\n half _Porosity;\n //#endif\n\n //#if _WETNESS\n int _WetnessMode;\n half _WetnessAmount;\n\t half _WetnessMin;\n half _WetnessMax;\n half _WetnessFalloff;\n\t half _WetnessAngleMin;\n float _WetnessShoreline;\n int _WetnessEffectorInvert;\n //#endif\n //#if _PUDDLES\n int _PuddleMode;\n\n half _PuddleAmount;\n half _PuddleFalloff;\n half4 _PuddleColor;\n half _PuddleNoiseFrequency;\n half _PuddleNoiseAmplitude;\n half _PuddleNoiseOffset;\n half _PuddleNoiseCenter;\n half _PuddleAngleMin;\n int _PuddleEffectorInvert;\n half _PuddleHeightDampening;\n //#endif\n\n \n //#if _RAINDROPS\n int _RainMode;\n int _RainUV;\n half4 _RainIntensityScale;\n //#endif\n\n\n\n\n float4 _SnowAlbedo_ST;\n half3 _SnowTint;\n half _SnowAmount;\n half _SnowAngle;\n half _SnowContrast;\n half _SnowVertexHeight;\n half _SnowMode;\n half3 _SnowWorldFade; // z is on/off\n \n float4 _SnowTraxAlbedo_ST;\n half3 _SnowTraxTint;\n\n half _SnowNoiseFreq; \n half _SnowNoiseAmp;\n half _SnowNoiseOffset;\n half _SnowStochasticContrast;\n half _SnowStochasticScale;\n\n half4 _SnowFresnelColor;\n half3 _SnowFresnelBSP;\n half4 _SnowSparkleTCI;\n half _SnowEffectorInvert;\n\n\n\n CBUFFER_END\n \n\n\n // -- Property used by ScenePickingPass\n #ifdef SCENEPICKINGPASS\n float4 _SelectionID;\n #endif\n \n // -- Properties used by SceneSelectionPass\n #ifdef SCENESELECTIONPASS\n int _ObjectId;\n int _PassValue;\n #endif\n \n \n // data across stages, stripped like the above.\n struct VertexToPixel\n {\n float4 pos : SV_POSITION;\n float3 worldPos : TEXCOORD0;\n float3 worldNormal : TEXCOORD1;\n float4 worldTangent : TEXCOORD2;\n float4 texcoord0 : TEXCOORD3;\n float4 texcoord1 : TEXCOORD4;\n float4 texcoord2 : TEXCOORD5;\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD6;\n // #endif\n\n #if _SNOWSPARKLES\n float4 screenPos : TEXCOORD7;\n #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD12;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD13;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD14;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD15;\n // #endif\n\n #if UNITY_ANY_INSTANCING_ENABLED\n UNITY_VERTEX_INPUT_INSTANCE_ID\n #endif // UNITY_ANY_INSTANCING_ENABLED\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n float4 previousPositionCS : TEXCOORD16; // Contain previous transform position (in case of skinning for example)\n float4 motionVectorCS : TEXCOORD17;\n #endif\n\n UNITY_VERTEX_OUTPUT_STEREO\n }; \n\n\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl\"\n #include \"Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialUtilities.hlsl\"\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl\"\n \n\n \n \n // data describing the user output of a pixel\n struct Surface\n {\n half3 Albedo;\n half Height;\n half3 Normal;\n half Smoothness;\n half3 Emission;\n half Metallic;\n half3 Specular;\n half Occlusion;\n half SpecularPower; // for simple lighting\n half Alpha;\n float outputDepth; // if written, SV_Depth semantic is used. ShaderData.clipPos.z is unused value\n // HDRP Only\n half SpecularOcclusion;\n half SubsurfaceMask;\n half Thickness;\n half CoatMask;\n half CoatSmoothness;\n half Anisotropy;\n half IridescenceMask;\n half IridescenceThickness;\n int DiffusionProfileHash;\n float SpecularAAThreshold;\n float SpecularAAScreenSpaceVariance;\n // requires _OVERRIDE_BAKEDGI to be defined, but is mapped in all pipelines\n float3 DiffuseGI;\n float3 BackDiffuseGI;\n float3 SpecularGI;\n float ior;\n float3 transmittanceColor;\n float atDistance;\n float transmittanceMask;\n // requires _OVERRIDE_SHADOWMASK to be defines\n float4 ShadowMask;\n\n // for decals\n float NormalAlpha;\n float MAOSAlpha;\n\n\n };\n\n // Data the user declares in blackboard blocks\n struct Blackboard\n {\n \n\thalf roadWear;\n\n\n float traxBuffer;\n\n\n half puddleAmount;\n\n\n float blackboardDummyData;\n };\n\n // data the user might need, this will grow to be big. But easy to strip\n struct ShaderData\n {\n float4 clipPos; // SV_POSITION\n float3 localSpacePosition;\n float3 localSpaceNormal;\n float3 localSpaceTangent;\n \n float3 worldSpacePosition;\n float3 worldSpaceNormal;\n float3 worldSpaceTangent;\n float tangentSign;\n\n float3 worldSpaceViewDir;\n float3 tangentSpaceViewDir;\n\n float4 texcoord0;\n float4 texcoord1;\n float4 texcoord2;\n float4 texcoord3;\n\n float2 screenUV;\n float4 screenPos;\n\n float4 vertexColor;\n bool isFrontFace;\n\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n\n float3x3 TBNMatrix;\n Blackboard blackboard;\n };\n\n struct VertexData\n {\n #if SHADER_TARGET > 30\n // uint vertexID : SV_VertexID;\n #endif\n float4 vertex : POSITION;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n\n // optimize out mesh coords when not in use by user or lighting system\n #if _URP && (_USINGTEXCOORD1 || _PASSMETA || _PASSFORWARD || _PASSGBUFFER)\n float4 texcoord1 : TEXCOORD1;\n #endif\n\n #if _URP && (_USINGTEXCOORD2 || _PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && defined(DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n #if _STANDARD && (_USINGTEXCOORD1 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER || _PASSFORWARDADD) && LIGHTMAP_ON)))\n float4 texcoord1 : TEXCOORD1;\n #endif\n #if _STANDARD && (_USINGTEXCOORD2 || (_PASSMETA || ((_PASSFORWARD || _PASSGBUFFER) && DYNAMICLIGHTMAP_ON)))\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n\n #if _HDRP\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n #endif\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side).\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n };\n\n struct TessVertex \n {\n float4 vertex : INTERNALTESSPOS;\n float3 normal : NORMAL;\n float4 tangent : TANGENT;\n float4 texcoord0 : TEXCOORD0;\n float4 texcoord1 : TEXCOORD1;\n float4 texcoord2 : TEXCOORD2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // float4 texcoord3 : TEXCOORD3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n float4 vertexColor : COLOR;\n // #endif\n\n // #if %EXTRAV2F0REQUIREKEY%\n // float4 extraV2F0 : TEXCOORD5;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // float4 extraV2F1 : TEXCOORD6;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // float4 extraV2F2 : TEXCOORD7;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // float4 extraV2F3 : TEXCOORD8;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // float4 extraV2F4 : TEXCOORD9;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // float4 extraV2F5 : TEXCOORD10;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // float4 extraV2F6 : TEXCOORD11;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // float4 extraV2F7 : TEXCOORD12;\n // #endif\n\n #if _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n float3 previousPositionOS : TEXCOORD13; // Contain previous transform position (in case of skinning for example)\n #if defined (_ADD_PRECOMPUTED_VELOCITY)\n float3 precomputedVelocity : TEXCOORD14;\n #endif\n #endif\n\n UNITY_VERTEX_INPUT_INSTANCE_ID\n UNITY_VERTEX_OUTPUT_STEREO\n };\n\n struct ExtraV2F\n {\n float4 extraV2F0;\n float4 extraV2F1;\n float4 extraV2F2;\n float4 extraV2F3;\n float4 extraV2F4;\n float4 extraV2F5;\n float4 extraV2F6;\n float4 extraV2F7;\n Blackboard blackboard;\n float4 time;\n };\n\n\n float3 WorldToTangentSpace(ShaderData d, float3 normal)\n {\n return mul(d.TBNMatrix, normal);\n }\n\n float3 TangentToWorldSpace(ShaderData d, float3 normal)\n {\n return mul(normal, d.TBNMatrix);\n }\n\n // in this case, make standard more like SRPs, because we can't fix\n // unity_WorldToObject in HDRP, since it already does macro-fu there\n\n #if _STANDARD\n float3 TransformWorldToObject(float3 p) { return mul(unity_WorldToObject, float4(p, 1)); };\n float3 TransformObjectToWorld(float3 p) { return mul(unity_ObjectToWorld, float4(p, 1)); };\n float4 TransformWorldToObject(float4 p) { return mul(unity_WorldToObject, p); };\n float4 TransformObjectToWorld(float4 p) { return mul(unity_ObjectToWorld, p); };\n float4x4 GetWorldToObjectMatrix() { return unity_WorldToObject; }\n float4x4 GetObjectToWorldMatrix() { return unity_ObjectToWorld; }\n #if (defined(SHADER_API_D3D11) || defined(SHADER_API_XBOXONE) || defined(UNITY_COMPILER_HLSLCC) || defined(SHADER_API_PSSL) || (SHADER_TARGET_SURFACE_ANALYSIS && !SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER))\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord, lod) tex.SampleLevel (sampler##tex,coord, lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord, lod) tex.SampleLevel (sampler##samplertex,coord, lod)\n #else\n #define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex2D (tex,coord,0,lod)\n #define UNITY_SAMPLE_TEX2D_SAMPLER_LOD(tex,samplertex,coord,lod) tex2D (tex,coord,0,lod)\n #endif\n\n #undef GetWorldToObjectMatrix()\n\n #define GetWorldToObjectMatrix() unity_WorldToObject\n\n\n #endif\n\n float3 GetCameraWorldPosition()\n {\n #if _HDRP\n return GetCameraRelativePositionWS(_WorldSpaceCameraPos);\n #else\n return _WorldSpaceCameraPos;\n #endif\n }\n\n #if _GRABPASSUSED\n #if _STANDARD\n TEXTURE2D(%GRABTEXTURE%);\n SAMPLER(sampler_%GRABTEXTURE%);\n #endif\n\n half3 GetSceneColor(float2 uv)\n {\n #if _STANDARD\n return SAMPLE_TEXTURE2D(%GRABTEXTURE%, sampler_%GRABTEXTURE%, uv).rgb;\n #else\n return SHADERGRAPH_SAMPLE_SCENE_COLOR(uv);\n #endif\n }\n #endif\n\n\n \n #if _STANDARD\n UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);\n float GetSceneDepth(float2 uv) { return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv)); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv)); } \n #else\n float GetSceneDepth(float2 uv) { return SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv); }\n float GetLinear01Depth(float2 uv) { return Linear01Depth(GetSceneDepth(uv), _ZBufferParams); }\n float GetLinearEyeDepth(float2 uv) { return LinearEyeDepth(GetSceneDepth(uv), _ZBufferParams); } \n #endif\n\n float3 GetWorldPositionFromDepthBuffer(float2 uv, float3 worldSpaceViewDir)\n {\n float eye = GetLinearEyeDepth(uv);\n float3 camView = mul((float3x3)GetObjectToWorldMatrix(), transpose(mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V)) [2].xyz);\n\n float dt = dot(worldSpaceViewDir, camView);\n float3 div = worldSpaceViewDir/dt;\n float3 wpos = (eye * div) + GetCameraWorldPosition();\n return wpos;\n }\n\n #if _HDRP\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return GetAbsolutePositionWS(TransformObjectToWorld(pos));\n }\n #else\n float3 ObjectToWorldSpacePosition(float3 pos)\n {\n return TransformObjectToWorld(pos);\n }\n #endif\n\n #if _STANDARD\n UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n float4 depthNorms = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv);\n float3 norms = DecodeViewNormalStereo(depthNorms);\n norms = mul((float3x3)GetWorldToViewMatrix(), norms) * 0.5 + 0.5;\n return norms;\n }\n #elif _HDRP && !_DECALSHADER\n \n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n NormalData nd;\n DecodeFromNormalBuffer(_ScreenSize.xy * uv, nd);\n return nd.normalWS;\n }\n #elif _URP\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n #include \"Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl\"\n #endif\n\n float3 GetSceneNormal(float2 uv, float3 worldSpaceViewDir)\n {\n #if (SHADER_LIBRARY_VERSION_MAJOR >= 10)\n return SampleSceneNormals(uv);\n #else\n float3 wpos = GetWorldPositionFromDepthBuffer(uv, worldSpaceViewDir);\n return normalize(-cross(ddx(wpos), ddy(wpos))) * 0.5 + 0.5;\n #endif\n\n }\n #endif\n\n #if _HDRP\n\n half3 UnpackNormalmapRGorAG(half4 packednormal)\n {\n // This do the trick\n packednormal.x *= packednormal.w;\n\n half3 normal;\n normal.xy = packednormal.xy * 2 - 1;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\n half3 UnpackNormal(half4 packednormal)\n {\n #if defined(UNITY_NO_DXT5nm)\n return packednormal.xyz * 2 - 1;\n #else\n return UnpackNormalmapRGorAG(packednormal);\n #endif\n }\n #endif\n #if _HDRP || _URP\n\n half3 UnpackScaleNormal(half4 packednormal, half scale)\n {\n #ifndef UNITY_NO_DXT5nm\n // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)\n // Note neutral texture like \"bump\" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5\n packednormal.x *= packednormal.w;\n #endif\n half3 normal;\n normal.xy = (packednormal.xy * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n }\t\n\n #endif\n\n\n void GetSun(out float3 lightDir, out float3 color)\n {\n lightDir = float3(0.5, 0.5, 0);\n color = 1;\n #if _HDRP\n if (_DirectionalLightCount > 0)\n {\n DirectionalLightData light = _DirectionalLightDatas[0];\n lightDir = -light.forward.xyz;\n color = light.color;\n }\n #elif _STANDARD\n\t\t\t lightDir = normalize(_WorldSpaceLightPos0.xyz);\n color = _LightColor0.rgb;\n #elif _URP\n\t Light light = GetMainLight();\n\t lightDir = light.direction;\n\t color = light.color;\n #endif\n }\n\n\n\n \n\n \n\n \n\n#ifndef __STACKABLEFUNCLIBRARY_INCLUDES__\n#define __STACKABLEFUNCLIBRARY_INCLUDES__\n\n #if _DEBUG_SAMPLECOUNT\n int _sampleCount;\n #define COUNTSAMPLE { _sampleCount++; }\n #else\n #define COUNTSAMPLE\n #endif\n\n SAMPLER(shared_linear_clamp_sampler);\n SAMPLER(shared_linear_repeat_sampler);\n SAMPLER(shared_point_repeat_sampler);\n\n\n\n half3 RGBtoOklab(half3 c) {\n\n const float3x3 invB = float3x3(0.4121656120, 0.2118591070, 0.0883097947,\n 0.5362752080, 0.6807189584, 0.2818474174,\n 0.0514575653, 0.1074065790, 0.6302613616);\n const float3x3 invA = float3x3(0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660);\n\n half3 lms = mul(invB, c);\n \n return mul(invA, sign(lms)*pow(abs(lms), 0.3333333333333));\n \n }\n\n half3 OklabtoRGB(half3 c) {\n\n const float3x3 fwdA = float3x3(1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480);\n \n const float3x3 fwdB = float3x3(4.0767245293, -1.2681437731, -0.0041119885,\n -3.3072168827, 2.6093323231, -0.7034763098,\n 0.2307590544, -0.3411344290, 1.7068625689);\n\n half3 lms = mul(fwdA, c);\n \n return mul(fwdB, (lms * lms * lms));\n }\n\n\n\n half3 HSVtoRGB(half3 c)\n {\n half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);\n return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);\n }\n\n half3 RGBtoHSV(half3 c)\n {\n half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));\n half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));\n\n float d = q.x - min(q.w, q.y);\n float e = 0.0001;\n return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n }\n\n\t\n\tfloat2 RotateUV(float2 uv, float amt)\n\t{\n\t\tuv -=0.5;\n\t\tfloat s = sin ( amt);\n\t\tfloat c = cos ( amt );\n\t\tfloat2x2 mtx = float2x2( c, -s, s, c);\n\t\tmtx *= 0.5;\n\t\tmtx += 0.5;\n\t\tmtx = mtx * 2-1;\n\t\tuv = mul ( uv, mtx );\n\t\tuv += 0.5;\n\t\treturn uv;\n\t}\n\n half3 AdjustContrast(half3 color, half contrast)\n {\n half3 comp = 0.5;\n #if !UNITY_COLORSPACE_GAMMA\n comp = 0.22;\n #endif\n color = saturate(lerp(comp, color, contrast));\n return color;\n }\n\n float2 DoParallaxOffset( half h, half height, half3 viewDir)\n {\n h = h * height - height/2.0;\n float3 v = normalize(viewDir);\n v.z += 0.42;\n return h * (v.xy / v.z);\n }\n\n\n\n #define SAMPLEBARY SampleTexBary\n\n struct SampleConfig\n {\n float2 uv0;\n float2 uv1;\n float2 uv2;\n float2 dx0;\n float2 dy0;\n float2 dx1;\n float2 dy1;\n float2 dx2;\n float2 dy2;\n float3 weights;\n float3 origWeights;\n };\n\n struct Config\n {\n float2 origUV; // unscaled uv\n float2 origScale;\n float2 origScale1;\n float2 origScale2;\n float2 uv; // no stocastic or triplanar\n float2 dx;\n float2 dy;\n SampleConfig uvT; // just stochastic, or just triplanar\n SampleConfig uvX; // stochastic and triplanar\n SampleConfig uvY;\n SampleConfig uvZ;\n\n \n float3 absVertNormal;\n half3 axisSign;\n float3 normal;\n };\n\n\n float2 Hash2D( float2 x )\n {\n float2 k = float2( 0.3183099, 0.3678794 );\n x = x*k + k.yx;\n return -1.0 + 2.0*frac( 16.0 * k*frac( x.x*x.y*(x.x+x.y)) );\n }\n\n float Noise2D(float2 p )\n {\n float2 i = floor( p );\n float2 f = frac( p );\n \n float2 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( dot( Hash2D( i + float2(0.0,0.0) ), f - float2(0.0,0.0) ), \n dot( Hash2D( i + float2(1.0,0.0) ), f - float2(1.0,0.0) ), u.x),\n lerp( dot( Hash2D( i + float2(0.0,1.0) ), f - float2(0.0,1.0) ), \n dot( Hash2D( i + float2(1.0,1.0) ), f - float2(1.0,1.0) ), u.x), u.y);\n }\n \n\n float2 WorleyHash2D(float2 p)\n {\n \t return frac(cos(mul(p, float2x2(-64.2,71.3,81.4,-29.8)))*8321.3); \n }\n float WorleyNoise2D(float2 p)\n {\n float dist = 1;\n float2 i = floor(p);\n float2 f = frac(p);\n \n for(int x = -1;x<=1;x++)\n {\n for(int y = -1;y<=1;y++)\n {\n float d = distance(WorleyHash2D(i+float2(x,y))+float2(x,y),f);\n dist = min(dist,d);\n }\n }\n return dist;\n\t\n }\n\n#ifndef PI\n #define PI 3.14159265359\n#endif\n\n#ifndef TAU \n #define TAU 6.283185307179586\n#endif\n\n float GetIntegerNoise(float2 p)\n {\n p = 53.7 * frac( (p*0.3183099) + float2(0.71,0.113));\n return frac( p.x*p.y*(p.x+p.y) );\n }\n\n float WorleyHash3D(float f)\n {\n return frac(sin(f)*43758.5453);\n }\n\n float WorleyHash31(float3 v)\n {\n return WorleyHash3D(dot(v, float3(253.14, 453.74, 183.3)));\n }\n\n float3 WorleyRandom3D( float3 p )\n {\n return frac(sin(float3(dot(p,float3(127.1,311.7,217.3)),dot(p,float3(269.5,183.3,431.1)), dot(p,float3(365.6,749.9,323.7))))*437158.5453);\n }\n\n float WorleyNoise3D(float3 uvw)\n {\n float noise = 0.0;\n \n float3 p = floor(uvw);\n float3 f = frac(uvw);\n \n float4 res = 1;\n for(int x = -1; x <=1; ++x)\n {\n for(int y = -1; y <=1; ++y)\n {\n for(int z = -1; z <=1; ++z)\n {\n float3 gp = p + float3(x, y, z);\n\n float3 v = WorleyRandom3D(gp);\n\n\t\t\t\t float3 diff = gp + v - uvw;\n \n float d = length(diff);\n \n if(d < res.x)\n {\n res.xyz = float3(d, res.x, res.y);\n }\n else if(d < res.y)\n {\n res.xyz = float3(res.x, d, res.y);\n }\n else if(d < res.z)\n {\n res.z = d;\n }\n \n res.w = WorleyHash31(gp);\n }\n }\n }\n\n return res.x;\n }\n \n \n float3 Hash3D( float3 p )\n {\n p = float3( dot(p,float3(127.1,311.7, 74.7)),\n dot(p,float3(269.5,183.3,246.1)),\n dot(p,float3(113.5,271.9,124.6)));\n\n return -1.0 + 2.0*frac(sin(p)*437.5453123);\n }\n\n float Noise3D( float3 p )\n {\n float3 i = floor( p );\n float3 f = frac( p );\n \n float3 u = f*f*(3.0-2.0*f);\n\n return lerp( lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,0.0) ), f - float3(0.0,0.0,0.0) ), \n dot( Hash3D( i + float3(1.0,0.0,0.0) ), f - float3(1.0,0.0,0.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,0.0) ), f - float3(0.0,1.0,0.0) ), \n dot( Hash3D( i + float3(1.0,1.0,0.0) ), f - float3(1.0,1.0,0.0) ), u.x), u.y),\n lerp( lerp( dot( Hash3D( i + float3(0.0,0.0,1.0) ), f - float3(0.0,0.0,1.0) ), \n dot( Hash3D( i + float3(1.0,0.0,1.0) ), f - float3(1.0,0.0,1.0) ), u.x),\n lerp( dot( Hash3D( i + float3(0.0,1.0,1.0) ), f - float3(0.0,1.0,1.0) ), \n dot( Hash3D( i + float3(1.0,1.0,1.0) ), f - float3(1.0,1.0,1.0) ), u.x), u.y), u.z );\n }\n\n\n float FBM2DHQ(float2 uv)\n {\n float f = 0.5000*Noise2D( uv ); uv *= 2.01;\n f += 0.2500*Noise2D( uv ); uv *= 1.96;\n f += 0.1250*Noise2D( uv );\n return f;\n }\n\n float FBM2DTexture(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv).g;\n }\n\n #if _TESSELLATION_ON\n float FBM2DTextureLOD(TEXTURE2D(tex), float2 uv)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv, _TessellationMipBias).g;\n }\n #endif\n float FBM3DHQ(float3 uv, float3 pN)\n {\n float f = 0.5000*Noise3D( uv ); uv *= 2.01;\n f += 0.2500*Noise3D( uv ); uv *= 1.96;\n f += 0.1250*Noise3D( uv );\n return f;\n }\n\n float FBM3DTextureGrad(TEXTURE2D(tex), float3 uv, float3 pN, float3 dx, float3 dy)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.zy, dx.zy, dy.zy).g;\n half B = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, dx.xz, dy.xz).g;\n half C = SAMPLE_TEXTURE2D_GRAD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, dx.xy, dy.xy).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n float FBM3DTexture(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half A = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.zy).g;\n half B = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xz + 0.33).g;\n half C = SAMPLE_TEXTURE2D(tex, shared_linear_repeat_sampler, uv.xy + 0.67).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n\n #if _TESSELLATION_ON\n float FBM3DTextureLOD(TEXTURE2D(tex), float3 uv, float3 pN)\n {\n half A = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.zy, _TessellationMipBias).g;\n half B = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xz + 0.33, _TessellationMipBias).g;\n half C = SAMPLE_TEXTURE2D_LOD(tex, shared_linear_repeat_sampler, uv.xy + 0.67, _TessellationMipBias).g;\n half3 triblend = saturate(pow(abs(pN), 4));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n return A * triblend.x + B * triblend.y + C * triblend.z;\n }\n #endif\n\n float DoNoiseWorldHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n float DoNoiseWorldTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseWorldTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.worldSpacePosition * frequency + offset, d.worldSpaceNormal);\n }\n #endif\n\n float DoNoiseWorldWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseWorldLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.worldSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalHQ(ShaderData d, float frequency, float offset)\n {\n return FBM3DHQ(d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n float DoNoiseLocalTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTexture(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseLocalTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM3DTextureLOD(tex, d.localSpacePosition * frequency + offset, d.localSpaceNormal);\n }\n #endif\n\n float DoNoiseLocalWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseLocalLQ(ShaderData d, float frequency, float offset)\n {\n return Noise3D(d.localSpacePosition * frequency + offset);\n }\n\n float DoNoiseUVHQ(ShaderData d, float frequency, float offset)\n {\n return FBM2DHQ(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVTexture(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTexture(tex, d.texcoord0.xy * frequency + offset);\n }\n\n #if _TESSELLATION_ON\n float DoNoiseUVTextureLOD(TEXTURE2D(tex), ShaderData d, float frequency, float offset)\n {\n return FBM2DTextureLOD(tex, d.texcoord0.xy * frequency + offset);\n }\n #endif\n\n float DoNoiseUVWorley(ShaderData d, float frequency, float offset)\n {\n return WorleyNoise2D(d.texcoord0.xy * frequency + offset);\n }\n\n float DoNoiseUVLQ(ShaderData d, float frequency, float offset)\n {\n return Noise2D(d.texcoord0.xy * frequency + offset);\n }\n\n \n #if _SURFACEGRADIENT \n\n #define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)\n\n \n \n half3 SurfaceGradientFromTBN(ShaderData d, half2 deriv)\n {\n return deriv.x * d.TBNMatrix[0] + deriv.y * d.TBNMatrix[1];\n }\n\n half2 TspaceNormalToDerivative(half3 vM)\n {\n const half scale = 1.0/128.0;\n const half3 vMa = abs(vM);\n const half z_ma = max(vMa.z, scale*max(vMa.x, vMa.y));\n\n return -half2(vM.x, vM.y)/z_ma;\n }\n\n half3 SurfgradFromVolumeGradient(ShaderData d, half3 grad)\n {\n return grad - dot(d.worldSpaceNormal, grad) * d.worldSpaceNormal;\n }\n\n half3 SurfgradFromTriplanarProjection(ShaderData d, half3 pN, half3 xN, half3 yN, half3 zN)\n {\n const half w0 = pN.x;\n const half w1 = pN.y;\n const half w2 = pN.z;\n\n half2 xD = TspaceNormalToDerivative(xN);\n half2 yD = TspaceNormalToDerivative(yN);\n half2 zD = TspaceNormalToDerivative(zN);\n\n half3 volumeGrad = half3(w2 * zD.x + w1 * yD.y, w2 * zD.y + w0 * xD.y, w0 * xD.x + w1 * yD.x);\n\n return SurfgradFromVolumeGradient(d, volumeGrad);\n }\n\n half3 ConvertNormalToGradient(ShaderData d, half3 normal)\n {\n half2 deriv = TspaceNormalToDerivative(normal);\n\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n half3 ConvertNormal2ToGradient(ShaderData d, half2 packedNormal)\n {\n half2 tNormal = packedNormal;\n half rcpZ = rsqrt(max(1 - dot(tNormal.x, tNormal.x) - dot(tNormal.y, tNormal.y), dot(HALF_EPS, HALF_EPS))); // Clamp to avoid INF\n half2 deriv = tNormal * -rcpZ;\n return SurfaceGradientFromTBN(d, deriv);\n }\n\n\n half3 ResolveNormalFromSurfaceGradient(ShaderData d, half3 gradient)\n {\n return normalize(d.worldSpaceNormal - gradient);\n }\n\n #endif // _SURFACEGRADIENT\n\n\n // normals are in surface gradient or world space depending on settings, and can also be generated by height\n half3 GetWorldSpaceNormal(ShaderData d, half3 normal, half pheight)\n {\n #if _SURFACEGRADIENT\n return ResolveNormalFromSurfaceGradient(d, normal);\n #elif _AUTONORMAL\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 crossX = cross(float3(0,1,0), dx);\n float3 crossY = cross(float3(0,1,0), dy);\n float3 dt = abs(dot(crossY, dx));\n float height = _AutoNormalStrength * 0.5 * pheight;\n float3 n = ((((height + ddx(height)) - height) * crossY) + (((height + ddy(height)) - height) * crossX)) * sign(dt);\n n.y *= -1.0;\n return TangentToWorldSpace(d, normalize((dt * float3(0,1,0)) - n).xzy);\n #else\n return TangentToWorldSpace(d, normal);\n \n #endif\n \n }\n\n void WaterBRDF (inout half3 albedo, inout half smoothness, half metallic, half wetFactor, half surfPorosity) \n {\n half porosity = saturate((( (1 - smoothness) - 0.5)) / max(surfPorosity, 0.001));\n half factor = lerp(1, 0.2, (1 - metallic) * porosity);\n albedo *= lerp(1.0, factor, wetFactor);\n smoothness = lerp(smoothness, 0.92f, wetFactor);\n }\n\n void OffsetUV(inout Config c, float2 offset)\n {\n c.uv += offset;\n c.uvT.uv0 += offset;\n c.uvT.uv1 += offset;\n c.uvT.uv2 += offset;\n c.uvX.uv0 += offset;\n c.uvX.uv1 += offset;\n c.uvX.uv2 += offset;\n c.uvY.uv0 += offset;\n c.uvY.uv1 += offset;\n c.uvY.uv2 += offset;\n c.uvZ.uv0 += offset;\n c.uvZ.uv1 += offset;\n c.uvZ.uv2 += offset;\n }\n\n float4 DecodePackedToFloat4(float v)\n {\n uint vi = (uint)(v * (256.0f * 256.0f * 256.0f * 256.0f));\n int ex = (int)(vi / (256 * 256 * 256) % 256);\n int ey = (int)((vi / (256 * 256)) % 256);\n int ez = (int)((vi / (256)) % 256);\n int ew = (int)(vi % 256);\n float4 e = float4(ex / 255.0, ey / 255.0, ez / 255.0, ew / 255.0);\n return e;\n }\n\n\n void TriangleGrid(float2 uv, float scale,\n out float w1, out float w2, out float w3,\n out int2 vertex1, out int2 vertex2, out int2 vertex3)\n {\n // Scaling of the input\n uv *= 3.464 * scale; // 2 * sqrt(3)\n\n // Skew input space into simplex triangle grid\n const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);\n float2 skewedCoord = mul(gridToSkewedGrid, uv);\n\n // Compute local triangle vertex IDs and local barycentric coordinates\n int2 baseId = int2(floor(skewedCoord));\n float3 temp = float3(frac(skewedCoord), 0);\n temp.z = 1.0 - temp.x - temp.y;\n if (temp.z > 0.0)\n {\n w1 = temp.z;\n w2 = temp.y;\n w3 = temp.x;\n vertex1 = baseId;\n vertex2 = baseId + int2(0, 1);\n vertex3 = baseId + int2(1, 0);\n }\n else\n {\n w1 = -temp.z;\n w2 = 1.0 - temp.y;\n w3 = 1.0 - temp.x;\n vertex1 = baseId + int2(1, 1);\n vertex2 = baseId + int2(1, 0);\n vertex3 = baseId + int2(0, 1);\n }\n }\n\n // Fast random hash function\n float2 SimpleHash2(float2 p)\n {\n return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);\n }\n\n\n half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)\n {\n // compute weight with height map\n const half epsilon = 1.0f / 1024.0f;\n half3 weights = half3(iWeights.x * (tex0 + epsilon), \n iWeights.y * (tex1 + epsilon),\n iWeights.z * (tex2 + epsilon));\n\n // Contrast weights\n half maxWeight = max(weights.x, max(weights.y, weights.z));\n half transition = contrast * maxWeight;\n half threshold = maxWeight - transition;\n half scale = 1.0f / transition;\n weights = saturate((weights - threshold) * scale);\n // Normalize weights.\n half weightScale = 1.0f / (weights.x + weights.y + weights.z);\n weights *= weightScale;\n return weights;\n }\n\n\n half3 PackedUnpackScaleNormal(half4 packedNormal, float scale)\n {\n #if _PACKEDFAST || _PACKEDFASTMETAL\n half3 normal;\n normal.xy = (packedNormal.ag * 2 - 1) * scale;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n return normal; \n #endif\n return UnpackScaleNormal(packedNormal, scale);\n }\n\n void InitStochasticDxDy(inout SampleConfig c, float2 origUV, float2 origScale)\n {\n c.dx0 = ddx(origUV) * origScale;\n c.dy0 = ddy(origUV) * origScale;\n c.dx1 = c.dx0;\n c.dx2 = c.dx0;\n c.dy1 = c.dy0;\n c.dy2 = c.dy0;\n }\n\n void PrepareStochasticUVs(float scale, float2 uv, out SampleConfig c)\n {\n // Get triangle info\n ZERO_INITIALIZE(SampleConfig, c);\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n c.uv0 = uv;\n c.uv1 = uv;\n c.uv2 = uv;\n \n c.uv0.xy += SimpleHash2(vertex1);\n c.uv1.xy += SimpleHash2(vertex2);\n c.uv2.xy += SimpleHash2(vertex3);\n c.weights = half3(w1, w2, w3);\n c.origWeights = half3(w1, w2, w3);\n }\n\n\n half3 LitBlendDetailNormal(half3 n1, half3 n2)\n {\n #if _SURFACEGRADIENT\n return n1 + n2;\n #else\n return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));\n #endif\n }\n\n float3 TriplanarBlendUnpackedRNM(float3 n1, float3 n2)\n {\n n1.z += 1;\n n2.xy = -n2.xy;\n return n1 * dot(n1, n2) / n1.z - n2;\n }\n\n float3 BlendToFlatNormal(ShaderData d, float3 bary, float contrast)\n {\n float3 dx = ddx(d.worldSpacePosition);\n float3 dy = ddy(d.worldSpacePosition);\n float3 flatNormal = normalize(cross(dy, dx));\n float mb = min(bary.x, min(bary.y, bary.z));\n mb = saturate(mb * contrast);\n return lerp(d.worldSpaceNormal, flatNormal, mb);\n }\n\n void InitConfigDxDy(inout Config c)\n {\n c.uvT.dx0 = ddx(c.uvT.uv0);\n c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1);\n c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2);\n c.uvT.dy2 = ddy(c.uvT.uv2);\n }\n\n void RotateConfig(inout Config c, half3 rotation)\n {\n c.uv = RotateUV(c.uv, rotation.x * TAU);\n c.uvT.uv0 = RotateUV(c.uvT.uv0, rotation.x * TAU);\n c.uvT.uv1 = RotateUV(c.uvT.uv1, rotation.y * TAU);\n c.uvT.uv2 = RotateUV(c.uvT.uv2, rotation.z * TAU);\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast)\n {\n Config c;\n ZERO_INITIALIZE(Config, c);\n\n float3 pos = d.worldSpacePosition;\n float3 normal = d.worldSpaceNormal;\n\n if (space > 0)\n {\n pos = d.localSpacePosition;\n normal = d.localSpaceNormal;\n }\n\n c.uv = d.texcoord0.xy;\n\n if (uvsource == 1)\n c.uv = d.texcoord1.xy;\n else if (uvsource == 2)\n c.uv = pos.yz * float2(1, -1);\n else if (uvsource == 3)\n c.uv = pos.xz * float2(1, -1);\n else if (uvsource == 4)\n c.uv = pos.xy * float2(1, -1);\n\n c.origUV = c.uv;\n c.origScale = scale.xy;\n c.origScale1 = scale1.xy;\n c.origScale2 = scale2.xy;\n\n c.uv = c.uv * scale.xy + scale.zw;\n c.dx = ddx(c.uv);\n c.dy = ddy(c.uv);\n\n c.normal = normal;\n c.uvT.uv0 = pos.zy * scale.xy + scale.zw;\n c.uvT.uv1 = pos.xz * scale1.xy + scale1.zw;\n c.uvT.uv2 = pos.xy * scale2.xy + scale2.zw;\n\n c.uvT.uv1 += 0.33;\n c.uvT.uv2 += 0.67;\n\n c.uvT.dx0 = ddx(c.uvT.uv0); c.uvT.dy0 = ddy(c.uvT.uv0);\n c.uvT.dx1 = ddx(c.uvT.uv1); c.uvT.dy1 = ddy(c.uvT.uv1);\n c.uvT.dx2 = ddx(c.uvT.uv2); c.uvT.dy2 = ddy(c.uvT.uv2);\n\n half3 triblend = saturate(pow(abs(c.normal), triplanarContrast));\n triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n c.uvT.weights = triblend;\n c.uvT.origWeights = triblend;\n c.axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n c.absVertNormal = abs(d.worldSpaceNormal);\n \n\n return c;\n }\n\n Config CreateConfig(ShaderData d, float4 scale, float4 scale1, float4 scale2, float space, int uvsource, half triplanarContrast,\n half3 bary, half blend)\n {\n d.worldSpaceNormal = BlendToFlatNormal(d, bary, blend);\n Config c = CreateConfig(d, scale, scale1, scale2, space, uvsource, triplanarContrast);\n return c;\n }\n\n #define TEXTURE2D_PARAM3(tex, ss) TEXTURE2D(tex), TEXTURE2D(tex_P1), TEXTURE2D(tex_P2), SAMPLER(ss)\n #define TEXTURE2D_ARGS3(textureName, samplerName) textureName, textureName##_P1, textureName##_P2, samplerName\n\n half4 TriSample(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0) * c.weights.x;\n }\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uv1, c.dx1, c.dy1) * c.weights.y;\n } \n\n UNITY_BRANCH\n if (c.weights.z > 0)\n {\n COUNTSAMPLE\n res += SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uv2, c.dx2, c.dy2) * c.weights.z;\n }\n\n return res;\n }\n\n half4 TriSampleBary(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float contrast, ShaderData d)\n {\n half4 r1 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv0, c.dx0, c.dy0);\n half4 r2 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv1, c.dx1, c.dy1);\n half4 r3 = SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv2, c.dx2, c.dy2);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n c.weights = BaryWeightBlend(c.origWeights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n\n \n half4 SampleTexBaryStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvX, contrast, d) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, contrast, d) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBary(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, contrast, d) * c.uvT.weights.z;\n\n return res;\n }\n\n \n half4 SampleTexBaryStochastic(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleBary(TEXTURE2D_ARGS(tex, ss), c.uvT, contrast, d);\n return ret;\n }\n\n half4 SampleTexBaryTriplanar(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n return ret;\n }\n\n half4 SampleTexBaryTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n half4 ret = TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n return ret;\n }\n\n \n half4 SampleTexBary(TEXTURE2D_PARAM(tex, ss), inout Config c, float contrast, ShaderData d)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uv, c.dx, c.dy);\n }\n\n half4 SampleTexStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n half4 SampleTexStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ) * c.uvT.weights.z;\n\n return res; \n }\n\n \n half4 SampleTexStochastic(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanar(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n return TriSample(TEXTURE2D_ARGS(tex, ss), c.uvT);\n }\n\n half4 SampleTexTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c)\n {\n return TriSampleP(TEXTURE2D_ARGS3(tex, ss), c.uvT);\n }\n \n half4 SampleTex(TEXTURE2D_PARAM(tex, ss), Config c)\n {\n COUNTSAMPLE\n return SAMPLE_TEXTURE2D(tex, ss, c.uv);\n }\n\n half3 UnpackNormalStochasticTriplanar(half4 dataX, half4 dataY, half4 dataZ, Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half3 tnormalX = PackedUnpackScaleNormal(dataX, normalStrength);\n half3 tnormalY = PackedUnpackScaleNormal(dataY, normalStrength);\n half3 tnormalZ = PackedUnpackScaleNormal(dataZ, normalStrength);\n\n #if _PACKEDFAST\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n ao = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #elif _PACKEDFASTMETAL\n smoothness = dataX.r * c.uvT.weights.x + dataY.r * c.uvT.weights.y + dataZ.r * c.uvT.weights.z;\n metal = dataX.b * c.uvT.weights.x + dataY.b * c.uvT.weights.y + dataZ.b * c.uvT.weights.z;\n #endif\n\n #if _SURFACEGRADIENT\n return SurfgradFromTriplanarProjection(d, c.uvT.weights, tnormalX, tnormalY, tnormalZ);\n #else\n // Swizzle world normals to match tangent space and apply RNM blend\n tnormalX = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.zy, c.absVertNormal.x), tnormalX);\n tnormalY = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xz, c.absVertNormal.y), tnormalY);\n tnormalZ = TriplanarBlendUnpackedRNM(half3(d.worldSpaceNormal.xy, c.absVertNormal.z), tnormalZ);\n\n tnormalX.z *= c.axisSign.x;\n tnormalY.z *= c.axisSign.y;\n tnormalZ.z *= c.axisSign.z;\n // Triblend normals and add to world normal\n half3 worldNormal = normalize(tnormalX.zyx * c.uvT.weights.x + tnormalY.xzy * c.uvT.weights.y + tnormalZ.xyz * c.uvT.weights.z);\n\n return WorldToTangentSpace(d, worldNormal);\n #endif\n }\n \n half3 SampleNormalStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n \n half3 SampleNormalStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n dataX = (TriSample(TEXTURE2D_ARGS(tex, ss), c.uvX));\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n dataY = (TriSample(TEXTURE2D_ARGS(tex_P1, ss), c.uvY));\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n dataZ = (TriSample(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ));\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n\n half3 SampleNormalTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 dataX = half4(0.5,0.5,1,0);\n half4 dataY = half4(0.5,0.5,1,0);\n half4 dataZ = half4(0.5,0.5,1,0);\n\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n {\n COUNTSAMPLE\n dataX = (SAMPLE_TEXTURE2D_GRAD(tex, ss, c.uvT.uv0, c.uvT.dx0, c.uvT.dy0));\n }\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n {\n COUNTSAMPLE\n dataY = (SAMPLE_TEXTURE2D_GRAD(tex_P1, ss, c.uvT.uv1, c.uvT.dx1, c.uvT.dy1));\n }\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n {\n COUNTSAMPLE\n dataZ = (SAMPLE_TEXTURE2D_GRAD(tex_P2, ss, c.uvT.uv2, c.uvT.dx2, c.uvT.dy2));\n }\n\n return UnpackNormalStochasticTriplanar(dataX, dataY, dataZ, c, d, normalStrength, smoothness, ao, metal);\n \n }\n\n half3 SampleNormalStochastic(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = TriSample(tex, ss, c.uvT);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n \n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half3 SampleNormal(TEXTURE2D_PARAM(tex, ss), Config c, ShaderData d, half normalStrength, inout half smoothness, inout half ao, inout half metal)\n {\n half4 normal = SAMPLE_TEXTURE2D(tex, ss, c.uv);\n #if _PACKEDFAST\n smoothness = normal.r;\n ao = normal.b;\n #elif _PACKEDFASTMETAL\n smoothness = normal.r;\n metal = normal.b;\n #endif\n\n #if _SURFACEGRADIENT\n return ConvertNormalToGradient(d, PackedUnpackScaleNormal(normal, normalStrength));\n #else\n return PackedUnpackScaleNormal(normal, normalStrength);\n #endif\n }\n\n half HeightBlend(half h1, half h2, half slope, half contrast)\n {\n h2 = 1 - h2;\n half tween = saturate((slope - min(h1, h2)) / max(abs(h1 - h2), 0.001)); \n half blend = saturate( ( tween - (1-contrast) ) / max(contrast, 0.001));\n return blend;\n }\n\n\n #if _POM\n float2 POM(TEXTURE2D_PARAM(tex, ss), Config c, float contrast, ShaderData d)\n {\n float2 curv = float2(0, 0);\n float refPlane = 0;\n\n float result = 0;\n int stepIndex = 0;\n int maxSamples = _POMMaxSamples;\n int minSamples = 4;\n float camDist = distance(_WorldSpaceCameraPos, d.worldSpacePosition);\n float distanceFade = 1 - saturate((camDist - _POMMin) / max(1, _POMFade));\n int numSteps = ( int )lerp( maxSamples, minSamples, dot( d.worldSpaceNormal, d.worldSpaceViewDir )) * distanceFade;\n if (numSteps < 1)\n numSteps = 1;\n float layerHeight = 1.0 / numSteps;\n float2 plane = _ParallaxHeight * ( d.tangentSpaceViewDir.xy / d.tangentSpaceViewDir.z ) * distanceFade;\n OffsetUV(c, refPlane * plane);\n float2 deltaTex = -plane * layerHeight;\n float2 prevTexOffset = 0;\n float prevRayZ = 1.0f;\n float prevHeight = 0.0f;\n float2 currTexOffset = deltaTex;\n float currRayZ = 1.0f - layerHeight;\n float currHeight = 0.0f;\n float intersection = 0;\n float2 finalTexOffset = 0;\n\n while ( stepIndex < numSteps + 1 )\n {\n result = dot( curv, currTexOffset * currTexOffset );\n Config cfg = c;\n OffsetUV(cfg, currTexOffset);\n currHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( currHeight > currRayZ )\n {\n stepIndex = numSteps + 1;\n }\n else\n {\n stepIndex++;\n prevTexOffset = currTexOffset;\n prevRayZ = currRayZ;\n prevHeight = currHeight;\n currTexOffset += deltaTex;\n currRayZ -= layerHeight * ( 1 - result );\n }\n }\n int sectionSteps = 10;\n int sectionIndex = 0;\n float newZ = 0;\n float newHeight = 0;\n while ( sectionIndex < sectionSteps )\n {\n intersection = ( prevHeight - prevRayZ ) / ( prevHeight - currHeight + currRayZ - prevRayZ );\n finalTexOffset = prevTexOffset + intersection * deltaTex;\n newZ = prevRayZ - intersection * layerHeight;\n Config cfg = c;\n OffsetUV(cfg, finalTexOffset);\n newHeight = SAMPLEBARY(TEXTURE2D_ARGS(tex, ss), cfg, contrast, d).a * (1 - result);\n\n if ( newHeight > newZ )\n {\n currTexOffset = finalTexOffset;\n currHeight = newHeight;\n currRayZ = newZ;\n deltaTex = intersection * deltaTex;\n layerHeight = intersection * layerHeight;\n }\n else\n {\n prevTexOffset = finalTexOffset;\n prevHeight = newHeight;\n prevRayZ = newZ;\n deltaTex = ( 1 - intersection ) * deltaTex;\n layerHeight = ( 1 - intersection ) * layerHeight;\n }\n sectionIndex++;\n }\n #if _PASSHADOWS\n if ( unity_LightShadowBias.z == 0.0 )\n {\n #endif\n if ( result > 1 )\n clip( -1 );\n #if _PASSHADOWS\n }\n #endif\n return finalTexOffset;\n }\n #endif\n\n \n\n // tess versions\n #if _TESSELLATION_ON\n half4 TriSampleLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleLODP(TEXTURE2D_PARAM3(tex, ss), inout SampleConfig c, float bias)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.weights.x > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias) * c.weights.x;\n\n UNITY_BRANCH\n if (c.weights.y > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P1, ss, c.uv1, bias) * c.weights.y;\n\n UNITY_BRANCH\n if (c.weights.z > 0)\n res += SAMPLE_TEXTURE2D_LOD(tex_P2, ss, c.uv2, bias) * c.weights.z;\n\n return res;\n }\n\n half4 TriSampleBaryLOD(TEXTURE2D_PARAM(tex, ss), inout SampleConfig c, float bias, float contrast)\n {\n half4 r1 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv0, bias);\n half4 r2 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv1, bias);\n half4 r3 = SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv2, bias);\n c.weights = BaryWeightBlend(c.weights, r1.a, r2.a, r3.a, contrast);\n return r1 * c.weights.x + r2 * c.weights.y + r3 * c.weights.z;\n }\n\n \n half4 SampleTexBaryLODStochasticTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n\n half4 SampleTexBaryLODStochasticTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n half4 res = 0;\n UNITY_BRANCH\n if (c.uvT.weights.x > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvX, bias, contrast) * c.uvT.weights.x;\n\n UNITY_BRANCH\n if (c.uvT.weights.y > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P1, ss), c.uvY, bias, contrast) * c.uvT.weights.y;\n\n UNITY_BRANCH\n if (c.uvT.weights.z > 0)\n res += TriSampleBaryLOD(TEXTURE2D_ARGS(tex_P2, ss), c.uvZ, bias, contrast) * c.uvT.weights.z;\n\n return res;\n }\n\n half4 SampleTexBaryLODStochastic(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleBaryLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias, contrast);\n }\n\n half4 SampleTexBaryLODTriplanar(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLOD(TEXTURE2D_ARGS(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLODTriplanarProjection(TEXTURE2D_PARAM3(tex, ss), Config c, float bias, float contrast)\n {\n return TriSampleLODP(TEXTURE2D_ARGS3(tex, ss), c.uvT, bias);\n }\n\n half4 SampleTexBaryLOD(TEXTURE2D_PARAM(tex, ss), Config c, float bias, float contrast)\n {\n return SAMPLE_TEXTURE2D_LOD(tex, ss, c.uv, bias);\n }\n\n\n #endif //_TESSELLATION_ON\n\n\n half3 FuzzyShade(ShaderData d, half height, half3 color, half3 normal, half coreMult, half edgeMult, half power)\n {\n float3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half dt = saturate(dot(d.worldSpaceViewDir, worldNormal));\n half dark = 1.0 - (coreMult * dt);\n half edge = pow(abs(1.0-dt), power) * edgeMult;\n return color * (dark + edge);\n }\n\n\thalf MicroShadow(ShaderData d, half3 normal, half height, half ao, half strength)\n\t{\n float3 sun;\n\t\tfloat3 sunColor;\n\t\tGetSun(sun, sunColor);\n\t\tfloat3 worldNormal = GetWorldSpaceNormal(d, normal, height);\n half shadow = saturate(abs(dot(worldNormal, sun)) + (ao * ao * 2.0) - 1.0);\n return 1 - ((1-shadow) * strength);\n\t}\n\n float4 QuickTriplanar(TEXTURE2D_PARAM(tex, ss), float3 worldPos, float3 worldNormal, float falloff, float tiling)\n\t{\n\t\tfloat3 projNormal = (pow(abs(worldNormal), falloff));\n\t\tprojNormal /= (projNormal.x + projNormal.y + projNormal.z) + 0.00001;\n\t\tfloat3 nsign = sign(worldNormal);\n\n\t\thalf4 xNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.zy * float2( nsign.x, 1.0));\n\t\thalf4 yNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xz * float2( nsign.y, 1.0));\n\t\thalf4 zNorm = SAMPLE_TEXTURE2D(tex, ss, tiling * worldPos.xy * float2( -nsign.z, 1.0));\n\t\treturn xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z;\n\t}\n\n\thalf Sparkle(ShaderData d, TEXTURE2D_PARAM(tex, ss), float2 screenUV, float2 uv, half tiling, half cutoff, half intensity)\n\t{\n\t\tfloat2 screenuv = screenUV * tiling;\n\t\tfloat noise = QuickTriplanar(TEXTURE2D_ARGS(tex, ss), d.worldSpacePosition, d.worldSpaceNormal, 4.5, tiling).x;\n\t\treturn ((1.0 - step((SAMPLE_TEXTURE2D(tex, ss, screenuv).x * noise.x), cutoff)) * intensity);\n\t}\n\n half Fresnel(ShaderData d, float3 worldSpaceNormal, half bias, half scale, half power)\n\t{\n\t\tfloat ndotv = dot( worldSpaceNormal, d.worldSpaceViewDir );\n\t\treturn bias + scale * pow( abs(1.0 - ndotv), power);\n\t}\n\n\n#endif\n\n\n\n\tsampler2D _Asphalt_Albedo;\n\tsampler2D _Asphalt_NormalSAO;\n\tsampler2D _Asphalt_MaskMap;\n\n\tTEXTURE2D(_WearMapA);\n\tTEXTURE2D(_WearMapB);\n\tTEXTURE2D(_WearNoise);\n\tsampler2D _Mask;\n\tTEXTURE2D(_Overlay_Albedo);\n\tTEXTURE2D(_Overlay_Normal);\n\tTEXTURE2D(_Overlay_Mask);\n\tTEXTURE2D(_Overlay_VariationMask);\n\n\tSamplerState road_linear_repeat_sampler;\n\tSamplerState road_linear_clamp_sampler;\n\n\tvoid Ext_SurfaceFunction0 (inout Surface o, inout ShaderData d)\n\t{\n\n\t\tfloat2 uv = d.texcoord0.xy;\n\n\t\t#if _ASPHALT_WORLDTRIPLANAR\n\t\t\t// base layer, triplanar\n\t\t\thalf3 triblend = saturate(pow(d.worldSpaceNormal, 4));\n\t\t\ttriblend /= max(dot(triblend, half3(1,1,1)), 0.0001);\n\n\t\t\tfloat2 uvX = d.worldSpacePosition.zy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvY = d.worldSpacePosition.xz * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tfloat2 uvZ = d.worldSpacePosition.xy * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t\tuvY += 0.33;\n\t\t\tuvZ += 0.67;\n\t\t\thalf3 axisSign = d.worldSpaceNormal < 0 ? -1 : 1;\n\t\t\tuvX.x *= axisSign.x;\n\t\t\tuvY.x *= axisSign.y;\n\t\t\tuvZ.x *= -axisSign.z;\n\n\t\t\t// 1 sample triplanar\n\t\t\tfloat2 uvT = uvZ;\n\t\t\tif (triblend.x > triblend.y && triblend.x > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvX;\n\t\t\t}\n\t\t\telse if (triblend.y > triblend.z)\n\t\t\t{\n\t\t\t\tuvT = uvY;\n\t\t\t}\n\t\t#else\n\t\t\tfloat2 uvT = uv * _Asphalt_Albedo_ST.xy + _Asphalt_Albedo_ST.zy;\n\t\t#endif\n\n\t\t#if _ASPHALTSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n\t\t float2 dx = ddx(uvT);\n\t\t float2 dy = ddy(uvT);\n TriangleGrid(uv, _AsphaltStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uvT;\n float2 uv1 = uvT;\n float2 uv2 = uvT;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = tex2Dgrad(_Asphalt_Albedo, uv0, dx, dy);\n half4 albedo1 = tex2Dgrad(_Asphalt_Albedo, uv1, dx, dy);\n half4 albedo2 = tex2Dgrad(_Asphalt_Albedo, uv2, dx, dy);\n\n\t\t weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _AsphaltStochasticContrast);\n\t\t half4 col = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n half4 norm0 = tex2Dgrad(_Asphalt_NormalSAO, uv0, dx, dy);\n half4 norm1 = tex2Dgrad(_Asphalt_NormalSAO, uv1, dx, dy);\n half4 norm2 = tex2Dgrad(_Asphalt_NormalSAO, uv2, dx, dy);\n\t\t half4 nsao = norm0 * weights.x + norm1 * weights.y + norm2 * weights.z;\n\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap0 = tex2Dgrad(_Asphalt_MaskMap, uv0, dx, dy);\n\t\t half4 mmap1 = tex2Dgrad(_Asphalt_MaskMap, uv1, dx, dy);\n half4 mmap2 = tex2Dgrad(_Asphalt_MaskMap, uv2, dx, dy);\n\t\t half4 mmap = mmap0 * weights.x + mmap1 * weights.y + mmap2 * weights.z;\n\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\n\t\t \n\t\t#else\n\t\t half4 col = tex2D(_Asphalt_Albedo, uvT);\n\t\t half4 nsao = tex2D(_Asphalt_NormalSAO, uvT);\n\t\t half metallic = 0;\n\t\t #if !_PACKEDFAST\n\t\t half4 mmap = tex2D(_Asphalt_MaskMap, uvT);\n\t\t\t nsao.r = mmap.a;\n\t\t\t nsao.b = mmap.g;\n\t\t\t metallic = mmap.r;\n\t\t #endif\n\t\t#endif\n\n\t\t#if _ALPHACUT\n clip(col.a - _AlphaThreshold);\n #endif\n\n\t\to.Albedo = col.rgb * _Asphalt_Tint.rgb;\n\t\to.Height = col.a;\n\t\t\n\t\thalf3 normal;\n\t\tnormal.xy = nsao.wy * 2 - 1;\n\t\tnormal.xy *= _Asphalt_NormalStrength;\n\t\tnormal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n\t\to.Normal = normal;\n\n\t\to.Smoothness = saturate(nsao.r + _Asphalt_Smoothness);\n\t\to.Metallic = metallic + _Asphalt_Metallic;\n\t\to.Occlusion = nsao.b;\n\n\t\t// lines\n\t\tfloat fw = fwidth(d.texcoord0.xy);\n\t\tfloat lod = saturate(fw * _Mask_TexelSize.zw);\n\t\thalf4 mask = tex2D(_Mask, d.texcoord0.xy);\n\t\t// soften in mips to prevent aliasing\n\t\tmask.xy = lerp(smoothstep(0.25-fw, 0.75+fw, mask.xy), mask.xy, lod);\n\t\t\n\t\thalf4 noise = _WearNoise.Sample(road_linear_repeat_sampler, d.worldSpacePosition.xz * _WearNoise_ST.xy + _WearNoise_ST.zw);\n\n\t\tfloat2 maskStr = (1.0 - (smoothstep(0., 0.8, noise.z) * _LineWear)) * mask.xy;\n\t\to.Albedo = lerp(o.Albedo, _LineColorA.rgb, mask.x * maskStr.x * _LineColorA.a);\n\t\to.Albedo = lerp(o.Albedo, _LineColorB.rgb, mask.y * maskStr.y * _LineColorB.a);\n\n\t\to.Normal.xy = lerp(o.Normal, float3(0,0,1), maskStr);\n\t\to.Smoothness = lerp(o.Smoothness, 0, maskStr);\n\t\to.Metallic *= 1.0 - maskStr;\n\t\to.Occlusion = lerp(o.Occlusion, 1, maskStr);\n\t\to.Emission += _LineColorA.rgb * maskStr.x * _LineEmissiveA;\n\t\to.Emission += _LineColorB.rgb * maskStr.y * _LineEmissiveB;\n\n\t\t// wear\n\t\t#if _WEAR_A\n\t\t\tmask.z = abs(_WearA_NoiseParams.y - mask.z);\n\t\t\tfloat2 wAUV = d.worldSpacePosition.xz;\n\t\t\twAUV = wAUV * _WearMapA_ST.xy + _WearMapA_ST.zw;\n\t\t\tfloat noiseA = saturate(lerp(0.5, noise, _WearA_NoiseParams.x)).x;\n\t\t\thalf3 wearA = UnpackNormal(_WearMapA.Sample(road_linear_repeat_sampler, wAUV));\n\t\t\thalf heightA = (wearA.x < 0.5 ? (2.0 * wearA.x * wearA.y) : (1.0 - 2.0 * (1.0 - wearA.x) * (1.0 - wearA.y)));\n\t\t\theightA = saturate(heightA * 4);\n\t\t\thalf wearAWeight = _WearA_PBR.w * noiseA * mask.z;\n\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearA_Tint.rgb * 2, wearAWeight * heightA);\n\t\t\to.Normal = lerp(o.Normal, wearA, _WearA_PBR.z * wearAWeight);\t\n\t\t\to.Occlusion += wearAWeight * _WearA_PBR.y;\n\t\t\to.Smoothness += wearAWeight * _WearA_PBR.x;\n\t\t\td.blackboard.roadWear = wearAWeight;\n\n #endif\n\n\t\t#if _WEAR_B\n\t\t\tmask.w = abs(_WearB_NoiseParams.y - mask.w);\n\t\t\tfloat2 wBUV = d.worldSpacePosition.xz;\n\t\t\twBUV = wBUV * _WearMapB_ST.xy + _WearMapB_ST.zw;\n\t\t\tfloat noiseB = saturate(lerp(0.5, noise, _WearB_NoiseParams.x)).y;\n\t\t\thalf3 wearB = UnpackNormal(_WearMapB.Sample(road_linear_repeat_sampler, wBUV));\n\t\t\thalf heightB = (wearB.x < 0.5 ? (2.0 * wearB.x * wearB.y) : (1.0 - 2.0 * (1.0 - wearB.x) * (1.0 - wearB.y)));\n\t\t\theightB = saturate(heightB * 4);\n\t\t\thalf wearBWeight = _WearB_PBR.w * noiseB * mask.w;\n\t\t\n\t\t\to.Albedo = lerp(o.Albedo, o.Albedo * _WearB_Tint.rgb * 2, wearBWeight * heightB);\n\t\t\to.Normal = lerp(o.Normal, wearB, _WearB_PBR.z * wearBWeight);\t\n\t\t\to.Occlusion += wearBWeight * _WearB_PBR.y;\n\t\t\to.Smoothness += wearBWeight * _WearB_PBR.x;\n\t\t#endif\n\n\t\t#if _OVERLAY\n\t\t\tfloat2 ouv = d.worldSpacePosition.xz * _Overlay_Albedo_ST.xy + _Overlay_Albedo_ST.zw;\n\t\t\thalf4 oAlbedo = _Overlay_Albedo.Sample(road_linear_repeat_sampler, ouv);\n\t\t\thalf3 oNormal = UnpackNormal(_Overlay_Normal.Sample(road_linear_repeat_sampler, ouv));\n\t\t\thalf4 oMask = _Overlay_Mask.Sample(road_linear_repeat_sampler, ouv);\n\t\t\tfloat2 vwsUV = d.worldSpacePosition.xz * _Overlay_VariationMask_ST.xy + _Overlay_VariationMask_ST.zw;\n\t\t\thalf varyWorldSpace = _Overlay_VariationMask.Sample(road_linear_repeat_sampler, vwsUV).g;\n\t\t\toAlbedo.a *= varyWorldSpace;\n\t\t\to.Albedo = lerp(o.Albedo, oAlbedo.rgb, oAlbedo.a);\n\t\t\to.Normal = lerp(o.Normal, oNormal.rgb, oAlbedo.a);\n\t\t\to.Smoothness = lerp(o.Smoothness, oMask.a, oAlbedo.a);\n\t\t\to.Occlusion = lerp(o.Occlusion, oMask.g, oAlbedo.a);\n\t\t\to.Metallic = lerp(o.Metallic, oMask.r, oAlbedo.a);\n\t\t#endif\n\n\t\to.Albedo = saturate(o.Albedo);\n\t\to.Smoothness = saturate(o.Smoothness);\n\t\to.Occlusion = saturate(o.Occlusion);\n\t}\n\n\n\n\n #if _TRAX_ON\n TEXTURE2D(_TraxAlbedo);\n TEXTURE2D(_TraxPackedNormal);\n TEXTURE2D(_TraxMask);\n\n sampler2D_float _GMSTraxBuffer;\n\n float4 _GMSTraxBuffer_TexelSize;\n float3 _GMSTraxBufferPosition;\n float _GMSTraxBufferWorldSize;\n float _GMSTraxFudgeFactor;\n\n float SampleTraxBufferLOD(float3 worldPos, float3 worldNormal)\n { \n // generate UVs for the buffer, which is moving\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 8);\n uv *= 0.5;\n uv += 0.5;\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float s = tex2Dlod(_GMSTraxBuffer, float4(uv, 0, 0)).r;\n\n return 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n }\n \n \n float SampleTraxBuffer(float3 worldPos, float3 worldNormal, out float3 norm)\n {\n float2 uv = worldPos.xz;\n uv -= _GMSTraxBufferPosition.xz;\n uv /= max(_GMSTraxBufferWorldSize, 1);\n float fade = saturate(distance(uv, float2(0.0, 0.0)));\n fade = 1 - pow(abs(fade), 3);\n uv *= 0.5;\n uv += 0.5;\n \n\n float2 offset = _GMSTraxBuffer_TexelSize.xy;\n\n float s = tex2D(_GMSTraxBuffer, uv).r;\n \n float s1 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, -1)).r;\n float s2 = tex2D(_GMSTraxBuffer, uv + offset * float2(-1, 0)).r;\n float s3 = tex2D(_GMSTraxBuffer, uv + offset * float2(1, 0)).r;\n float s4 = tex2D(_GMSTraxBuffer, uv + offset * float2(0, 1)).r;\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n float vn = saturate(sign(dot(worldNormal, float3(0, 1, 0))));\n float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn;\n \n // generate normals\n norm.x = (s1 - s4) * 0.25; \n norm.y = (s2 - s3) * 0.25;\n norm.z = 2;\n norm = normalize(norm);\n \n norm.xy *= 1 - r;\n \n return r;\n }\n #endif\n\n void Ext_ModifyTessellatedVertex1 (inout VertexData v, inout ExtraV2F d)\n {\n #if _TESSELLATION_ON && _TRAX_ON && _HAS_LIT_TESSELLATION\n \n float3 worldSpacePosition = TransformObjectToWorld(v.vertex.xyz);\n float3 worldSpaceNormal = TransformObjectToWorld(v.normal);\n\n float traxBuffer = SampleTraxBufferLOD(worldSpacePosition, worldSpaceNormal);\n d.blackboard.traxBuffer = traxBuffer;\n float2 uv = worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n half albedo = SAMPLE_TEXTURE2D_LOD(_TraxAlbedo, shared_linear_repeat_sampler, uv, _TraxMipBias).a;\n\n float traxOffset = albedo * _TraxDisplacementStrength;\n traxOffset *= 1 - v.texcoord0.z;\n traxOffset *= _TessellationDisplacement;\n float dig = _TraxDisplacementDepth * (1 - v.texcoord0.z);\n float3 traxVertex = d.blackboard.originalVertexPosition + (v.normal * (traxOffset - dig));\n v.vertex.xyz = lerp(traxVertex, v.vertex.xyz, traxBuffer);\n\n d.blackboard.vertexHeightOffset = lerp(traxOffset-dig, d.blackboard.vertexHeightOffset, traxBuffer);\n\n #endif\n\n }\n\n void Ext_SurfaceFunction1 (inout Surface o, inout ShaderData d)\n {\n #if _TRAX_ON\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _TraxAlbedo_ST.xy + _TraxAlbedo_ST.zw;\n float2 fsdx = ddx(uv);\n float2 fsdy = ddy(uv);\n\n float3 traxNormal;\n float traxBuffer = SampleTraxBuffer(d.worldSpacePosition, d.worldSpaceNormal, traxNormal);\n \n #if _TESSELLATION_ON\n traxBuffer -= _TraxDisplacementDepth;\n #endif\n\n d.blackboard.traxBuffer = traxBuffer;\n\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxAlbedo, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n albedo.rgb *= _TraxTint.rgb;\n half4 normalSample = SAMPLE_TEXTURE2D_GRAD(_TraxPackedNormal, shared_linear_repeat_sampler, uv, fsdx, fsdy);\n COUNTSAMPLE\n COUNTSAMPLE\n\n\n half smoothness = normalSample.r;\n half ao = normalSample.b;\n half3 normal;\n normal.xy = (normalSample.ag * 2 - 1) * _TraxNormalStrength;\n normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));\n\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n\n \n half h = HeightBlend(albedo.a, o.Alpha, traxBuffer, _TraxHeightContrast);\n\n h = lerp(traxBuffer, h, _TraxInterpContrast);\n\n o.Albedo = lerp(albedo, o.Albedo, h);\n\n #if _SURFACEGRADIENT\n o.Normal = lerp(normal, o.Normal, h);\n #else\n o.Normal = lerp(normal + traxNormal, o.Normal, h);\n #endif\n \n o.Smoothness = lerp(smoothness, o.Smoothness, h);\n o.Occlusion = lerp(ao, o.Occlusion, h);\n }\n #endif\n }\n\n\n\n\n TEXTURE2D(_PuddleNoiseTex);\n\n #if _RAINDROPS\n TEXTURE2D(_RainDropTexture);\n half _Global_RainIntensity;\n #endif\n\n #if _WETNESS\n half2 _Global_WetnessParams; // global, not in cbuffer\n #endif\n \n #if _RAINDROPS\n half2 ComputeRipple(float2 uv, half time, half weight)\n {\n half4 ripple = SAMPLE_TEXTURE2D(_RainDropTexture, shared_linear_repeat_sampler, uv);\n COUNTSAMPLE\n ripple.yz = ripple.yz * 2 - 1;\n\n half dropFrac = frac(ripple.w + time);\n half timeFrac = dropFrac - 1.0 + ripple.x;\n half dropFactor = saturate(0.2f + weight * 0.8 - dropFrac);\n half finalFactor = dropFactor * ripple.x * \n sin( clamp(timeFrac * 9.0f, 0.0f, 3.0f) * 3.14159265359);\n\n return half2(ripple.yz * finalFactor);\n }\n #endif\n\n half2 DoRain(float3 worldPos, half2 waterNorm, float2 uv, out half2 ripple)\n {\n #if _RAINDROPS\n float rainIntensity = _RainIntensityScale.x;\n if (_RainMode > 1)\n {\n rainIntensity = _Global_RainIntensity;\n }\n\n if (_RainUV > 0.5)\n {\n uv = worldPos.xz;\n }\n\n float dist = distance(GetCameraWorldPosition(), worldPos);\n rainIntensity *= 1.0 - saturate(dist/_RainIntensityScale.w);\n\n half dropStrength = rainIntensity;\n const float4 timeMul = float4(1.0f, 0.85f, 0.93f, 1.13f); \n half4 timeAdd = float4(0.0f, 0.2f, 0.45f, 0.7f);\n half4 times = _Time.yyyy;\n times = frac((times * float4(1, 0.85, 0.93, 1.13) + float4(0, 0.2, 0.45, 0.7)) * 1.6);\n\n float2 ruv1 = uv * _RainIntensityScale.yy;\n float2 ruv2 = ruv1;\n\n half4 weights = rainIntensity.xxxx - float4(0, 0.25, 0.5, 0.75);\n half2 ripple1 = ComputeRipple(ruv1 + float2( 0.25f,0.0f), times.x, weights.x);\n half2 ripple2 = ComputeRipple(ruv2 + float2(-0.55f,0.3f), times.y, weights.y);\n half2 ripple3 = ComputeRipple(ruv1 + float2(0.6f, 0.85f), times.z, weights.z);\n half2 ripple4 = ComputeRipple(ruv2 + float2(0.5f,-0.75f), times.w, weights.w);\n weights = saturate(weights * 4);\n\n half2 rippleNormal = half2( weights.x * ripple1.xy +\n weights.y * ripple2.xy + \n weights.z * ripple3.xy + \n weights.w * ripple4.xy);\n\n ripple = rippleNormal * dropStrength * rainIntensity;\n waterNorm = lerp(waterNorm, normalize(half3(rippleNormal.xy + rippleNormal.xy, 1)).xy, rainIntensity * dropStrength); \n return waterNorm; \n #else\n return waterNorm;\n #endif\n }\n\n half _Global_PuddleParams; // this is a global, so keep it out of the cbuffer\n void GetPuddleParams(ShaderData d, inout float puddleMask, inout float pudHeight)\n {\n #if _PUDDLES || _GLOBALPUDDLES\n pudHeight = _PuddleAmount;\n if (_PuddleMode > 0)\n pudHeight = _Global_PuddleParams; \n\n\n #if _PUDDLEEFFECTOR\n if (_PuddleEffectorInvert < 0.5)\n pudHeight += d.blackboard.effectorWeight;\n else\n pudHeight -= d.blackboard.effectorWeight;\n\n pudHeight = saturate(pudHeight);\n #endif\n\n half dt = dot(d.worldSpaceNormal, float3(0,1,0));\n\t dt -= _PuddleAngleMin;\n dt = saturate(dt * _PuddleFalloff);\n puddleMask *= dt;\n #endif\n }\n \n void Ext_ModifyTessellatedVertex2 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _PUDDLES && _HAS_LIT_TESSELLATION\n\n ShaderData d;\n ZERO_INITIALIZE(ShaderData, d);\n d.texcoord0 = v.texcoord0;\n d.localSpacePosition = v.vertex.xyz;\n d.localSpaceNormal = v.normal;\n d.worldSpacePosition = ObjectToWorldSpacePosition(v.vertex.xyz);\n d.worldSpaceNormal = TransformObjectToWorld(v.normal);\n #if _PUDDLEEFFECTOR\n d.blackboard.effectorWeight = e.blackboard.effectorWeight;\n #endif\n half mask = 1;\n half pudHeight = 1;\n\n // save some ops by doing this in 2d\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTextureLOD(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n\n mask = saturate(mask);\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float height = pudHeight * mask;\n \n if (e.blackboard.vertexHeightOffset < height)\n {\n e.blackboard.vertexHeightOffset = height;\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n }\n #endif\n }\n\n\n#if _WETNESS\n\n float GetWetnessLevel(Surface o, ShaderData d, float wetnessMask)\n {\n\n float wetLevel = clamp(_WetnessAmount, _WetnessMin, _WetnessMax);\n \n if (_WetnessMode > 0)\n wetLevel = clamp(wetLevel, _Global_WetnessParams.x, _Global_WetnessParams.y);\n\n #if _WETNESSEFFECTOR\n if (_WetnessEffectorInvert < 0.5)\n wetLevel += d.blackboard.effectorWeight;\n else\n wetLevel -= d.blackboard.effectorWeight;\n\n wetLevel = saturate(wetLevel);\n #endif\n\n wetLevel = saturate(wetLevel + (1 - saturate(d.worldSpacePosition.y - _WetnessShoreline)));\n float3x3 tbn = float3x3(d.worldSpaceTangent, cross(d.worldSpaceTangent, d.worldSpaceNormal), d.worldSpaceNormal);\n float dt = dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0));\n dt -= _WetnessAngleMin;\n dt = saturate(dt * _WetnessFalloff * wetLevel);\n dt *= wetnessMask;\n return dt;\n }\n#endif\n \n\n void Ext_SurfaceFunction2 (inout Surface o, inout ShaderData d)\n {\n half wetnessLevel = 0;\n #if _WETNESS\n wetnessLevel = GetWetnessLevel(o, d, 1); // mask one day?\n #endif\n\n half depthMask = 0;\n half depth = 0;\n\n #if _PUDDLES\n half mask = 1;\n half pudHeight = 1;\n #if _PUDDLENOISE\n float2 nuv = d.texcoord0.xy;\n #if _PUDDLENOISEWORLD\n nuv = d.worldSpacePosition.xz;\n #elif _PUDDLENOISELOCAL\n nuv = d.localSpacePosition.xz;\n #endif\n\n #if _PUDDLENOISEHQ\n mask = (FBM2DHQ(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISETEXTURE\n mask = (FBM2DTexture(_PuddleNoiseTex, nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #elif _PUDDLENOISEWORLEY\n mask = (WorleyNoise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #else\n mask = (Noise2D(nuv * _PuddleNoiseFrequency + _PuddleNoiseOffset) * _PuddleNoiseAmplitude + _PuddleNoiseCenter);\n #endif\n #endif\n\n GetPuddleParams(d, mask, pudHeight);\n float oHeight = o.Height;\n oHeight = lerp(o.Height, 0.5, _PuddleHeightDampening);\n \n pudHeight *= mask;\n depth = pudHeight - oHeight;\n depthMask = saturate(depth * _PuddleFalloff);\n depthMask *= _PuddleColor.a;\n depth = oHeight - pudHeight;\n\n // extend wetness slighting higher than the puddle\n half wetmask = saturate((pudHeight + 0.05 - oHeight) * _PuddleFalloff);\n wetnessLevel = max(wetmask, wetnessLevel);\n d.blackboard.puddleAmount = saturate(pudHeight);\n #endif\n\n \n #if _WETNESS || _PUDDLES\n half3 waterNorm = half3(0,0,1);\n half3 wetAlbedo = o.Albedo;\n half wetSmoothness = o.Smoothness;\n #if _PUDDLES\n wetAlbedo *= _PuddleColor.rgb;\n #endif\n WaterBRDF(wetAlbedo, wetSmoothness, o.Metallic, wetnessLevel, _Porosity);\n\n half ri = 0;\n half2 ripple = 0;\n #if (_RAINDROPS || _GLOBALRAIN) && (_PUDDLES || _GLOBALPUDDLES)\n ri = _RainIntensityScale.z;\n waterNorm.xy = DoRain(d.worldSpacePosition, waterNorm.xy, d.texcoord0.xy, ripple) * depthMask;\n #endif\n\n o.Normal = lerp(o.Normal, waterNorm, depthMask);\n o.Normal = lerp(o.Normal, LitBlendDetailNormal(o.Normal, half3(ripple.xy, 1)), saturate(ri - depthMask) * wetnessLevel);\n o.Occlusion = lerp(o.Occlusion, 1, depthMask);\n o.Smoothness = lerp(o.Smoothness, wetSmoothness, wetnessLevel);\n o.Albedo = lerp(o.Albedo, wetAlbedo, wetnessLevel);\n o.Emission *= 1 + depth;\n o.Metallic *= 1 + depth;\n o.Specular *= 1 + depth;\n\n #endif\n\n }\n\n\n\n\n TEXTURE2D(_SnowAlbedo);\n TEXTURE2D(_SnowNormal);\n TEXTURE2D(_SnowMaskMap);\n\n TEXTURE2D(_SnowTraxAlbedo);\n TEXTURE2D(_SnowTraxNormal);\n TEXTURE2D(_SnowTraxMaskMap);\n TEXTURE2D(_SnowSparkleNoise);\n\n float _Global_SnowLevel;\n float2 _Global_SnowWorldFade;\n\n void Ext_ModifyVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _SNOW && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n snowAmount = saturate(snowAmount) * amount;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n v.vertex.xyz = v.vertex.xyz + displacementVec * snowAmount * snowAmount * _SnowVertexHeight;\n #endif\n }\n\n void Ext_ModifyTessellatedVertex3 (inout VertexData v, inout ExtraV2F e)\n {\n #if _TESSELLATION_ON && _SNOW && _HAS_LIT_TESSELLATION && !__ROADSHADER__\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += e.blackboard.effectorWeight;\n else\n amount -= e.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float3 worldNormal = mul((float3x3)GetWorldToObjectMatrix(), v.normal);\n float snowAmount = dot(worldNormal, float3(0,1,0)) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast * 0.5;\n float3 worldPos = ObjectToWorldSpacePosition(v.vertex.xyz);\n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((worldPos.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n snowAmount = saturate(snowAmount) * amount;\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(worldPos.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n snowAmount = saturate(snowAmount);\n\n #if _LAYERVERTEXMASK\n snowAmount *= v.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= e.blackboard.weightTextureMask.a;\n #endif\n\n float3 displacementVec = mul((float3x3)GetWorldToObjectMatrix(), float3(0,1,0));\n half heightMap = SAMPLE_TEXTURE2D_LOD(_SnowAlbedo, shared_linear_repeat_sampler, worldPos.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw, 2);\n\n float height = max(_SnowVertexHeight * 3 * snowAmount + snowAmount * heightMap, e.blackboard.vertexHeightOffset);\n #if _TRAX_ON\n height *= e.blackboard.traxBuffer;\n #endif\n e.blackboard.vertexHeightOffset = height;\n\n height -= _TessellationOffset; \n // dampen cracks\n height *= 1 - v.texcoord0.z;\n height *= _TessellationDisplacement;\n\n v.vertex.xyz = e.blackboard.originalVertexPosition + v.normal * height;\n \n #endif\n\n }\n\n void SampleSnowSurface(TEXTURE2D_PARAM(alb, ss), TEXTURE2D_PARAM(norm, ss2), TEXTURE2D_PARAM(mask, ss3),\n ShaderData d, float2 uv, float2 dx, float2 dy, out half4 albedo, out half3 normal, out half2 smoothAO)\n {\n #if _SNOWSTOCHASTIC\n float w1, w2, w3;\n int2 vertex1, vertex2, vertex3;\n TriangleGrid(uv, _SnowStochasticScale, w1, w2, w3, vertex1, vertex2, vertex3);\n\n // Assign random offset to each triangle vertex\n float2 uv0 = uv;\n float2 uv1 = uv;\n float2 uv2 = uv;\n \n uv0.xy += SimpleHash2(vertex1);\n uv1.xy += SimpleHash2(vertex2);\n uv2.xy += SimpleHash2(vertex3);\n half3 weights = half3(w1, w2, w3);\n\n half4 albedo0 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv0, dx, dy);\n half4 albedo1 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv1, dx, dy);\n half4 albedo2 = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n weights = BaryWeightBlend(weights, albedo0.a, albedo1.a, albedo2.a, _SnowStochasticContrast);\n albedo = albedo0 * weights.x + albedo1 * weights.y + albedo2 * weights.z;\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 n0 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv0, dx, dy);\n half4 n1 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv1, dx, dy);\n half4 n2 = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n\n half4 snowNormSamp = n0 * weights.x + n1 * weights.y + n2 * weights.z;\n\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask0 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv0, dx, dy);\n half4 snowMask1 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv1, dx, dy);\n half4 snowMask2 = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv2, dx, dy);\n COUNTSAMPLE\n COUNTSAMPLE\n COUNTSAMPLE\n half4 snowMask = snowMask0 * weights.x + snowMask1 * weights.y + snowMask2 * weights.z;\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #else // not stochastic\n albedo = SAMPLE_TEXTURE2D_GRAD(alb, ss, uv, dx, dy);\n COUNTSAMPLE\n\n normal = half3(0,0,1);\n smoothAO = half2(0, 1);\n\n #if !_AUTONORMAL\n half4 snowNormSamp = SAMPLE_TEXTURE2D_GRAD(norm, ss2, uv, dx, dy);\n COUNTSAMPLE\n normal = PackedUnpackScaleNormal(snowNormSamp, 1);\n #if _SURFACEGRADIENT\n normal = ConvertNormalToGradient(d, normal);\n #endif\n \n #if _PACKEDFAST\n smoothAO.x = snowNormSamp.r;\n smoothAO.y = snowNormSamp.b;\n #endif\n #endif\n\n #if _SNOWMASKMAP && !_PACKEDFAST\n half4 snowMask = SAMPLE_TEXTURE2D_GRAD(mask, ss3, uv, dx, dy);\n COUNTSAMPLE\n smoothAO.x = snowMask.a;\n smoothAO.y = snowMask.g;\n #endif\n #endif // stochastic\n }\n\n \n void Ext_SurfaceFunction3 (inout Surface o, ShaderData d)\n {\n #if _SNOW\n float amount = _SnowAmount;\n if (_SnowMode > 0)\n amount = _Global_SnowLevel;\n\n #if _SNOWEFFECTOR\n if (_SnowEffectorInvert < 0.5)\n amount += d.blackboard.effectorWeight;\n else\n amount -= d.blackboard.effectorWeight;\n\n amount = saturate(amount);\n #endif\n\n float snowAmount = lerp(dot(GetWorldSpaceNormal(d, o.Normal, o.Alpha), float3(0,1,0)), dot(d.worldSpaceNormal, float3(0,1,0)), amount * 0.8) + 1;\n snowAmount -= _SnowAngle;\n snowAmount *= _SnowContrast;\n snowAmount = saturate(snowAmount) - (1-amount) * (1-amount);\n \n if (_SnowWorldFade.z > 0)\n {\n float2 swf = _SnowWorldFade.xy;\n if (_SnowWorldFade.z > 1)\n swf = _Global_SnowWorldFade.xy;\n float worldFade = saturate((d.worldSpacePosition.y - swf.x) / max(swf.y, 1));\n snowAmount *= worldFade;\n }\n\n #if _SNOWNOISE\n snowAmount *= 1 - saturate(1 - (snowAmount * 2 - 1)) * Noise2D(d.worldSpacePosition.xz * _SnowNoiseFreq + _SnowNoiseOffset) * _SnowNoiseAmp;\n #endif\n\n // use height map during transition to full coverage\n float hamount = saturate(amount * 1.25);\n snowAmount -= o.Height * (1-hamount);\n \n #if _PUDDLES\n snowAmount -= d.blackboard.puddleAmount * (1-(hamount*hamount));\n #endif\n\n #if _ROADWEAR\n snowAmount -= d.blackboard.roadWear * (1-(hamount*hamount));\n #endif\n \n snowAmount = saturate(snowAmount);\n\n float2 uv = d.worldSpacePosition.xz * float2(1, -1) * _SnowAlbedo_ST.xy + _SnowAlbedo_ST.zw;\n float2 dx = ddx(uv);\n float2 dy = ddy(uv);\n\n #if _TRAX_ON\n float2 tuv = d.worldSpacePosition.xz * float2(1, -1) * _SnowTraxAlbedo_ST.xy + _SnowTraxAlbedo_ST.zw;\n float2 tdx = ddx(uv);\n float2 tdy = ddy(uv);\n #endif\n\n #if _LAYERVERTEXMASK\n snowAmount *= d.vertexColor.a;\n #elif _LAYERTEXTUREMASK && _HAS_WEIGHTTEXTURE_MASK\n snowAmount *= d.blackboard.weightTextureMask.a;\n #endif\n\n UNITY_BRANCH\n if (snowAmount > 0)\n {\n half4 snowAlbedo;\n half3 snowNormal;\n half2 snowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowMaskMap, shared_linear_repeat_sampler), d, uv, dx, dy, snowAlbedo, snowNormal, snowSmoothAO);\n\n snowAlbedo.rgb *= _SnowTint.rgb;\n\n #if _TRAX_ON\n half traxBuffer = 1 - d.blackboard.traxBuffer;\n UNITY_BRANCH\n if (traxBuffer > 0)\n {\n half4 tsnowAlbedo;\n half3 tsnowNormal;\n half2 tsnowSmoothAO;\n SampleSnowSurface(TEXTURE2D_ARGS(_SnowTraxAlbedo, shared_linear_repeat_sampler), TEXTURE2D_ARGS(_SnowTraxNormal, shared_linear_repeat_sampler),\n TEXTURE2D_ARGS(_SnowTraxMaskMap, shared_linear_repeat_sampler), d, tuv, tdx, tdy, tsnowAlbedo, tsnowNormal, tsnowSmoothAO);\n\n tsnowAlbedo.rgb *= _SnowTraxTint;\n half h = HeightBlend(snowAlbedo.a, tsnowAlbedo.a, traxBuffer, 0.5);\n snowAlbedo = lerp(snowAlbedo, tsnowAlbedo, h);\n snowNormal = lerp(snowNormal, tsnowNormal, h);\n snowSmoothAO = lerp(snowSmoothAO, tsnowSmoothAO, h);\n }\n #endif\n\n #if _SNOWFRESNEL || _SNOWFRESNELNORMAL\n half3 wsn = d.worldSpaceNormal;\n #if _SNOWFRESNELNORMAL\n wsn = GetWorldSpaceNormal(d, snowNormal, snowAlbedo.a);\n #endif\n half fresnel = Fresnel(d, wsn, _SnowFresnelBSP.x, _SnowFresnelBSP.y, _SnowFresnelBSP.z);\n snowAlbedo.rgb = lerp(snowAlbedo.rgb, _SnowFresnelColor.rgb, fresnel);\n #endif\n\n #if _SNOWSPARKLES\n float sparkles = Sparkle(d, TEXTURE2D_ARGS(_SnowSparkleNoise, shared_point_repeat_sampler), d.screenUV, d.worldSpacePosition.xz, _SnowSparkleTCI.x, _SnowSparkleTCI.y, _SnowSparkleTCI.z);\n snowAlbedo = saturate(snowAlbedo + sparkles);\n snowSmoothAO.x += sparkles;\n o.Emission += sparkles * _SnowSparkleTCI.w * snowAmount;\n #endif\n\n #if !_AUTONORMAL\n o.Normal = lerp(o.Normal, snowNormal, snowAmount);\n #endif\n\n o.Albedo = lerp(o.Albedo, snowAlbedo.rgb, snowAmount);\n o.Alpha = lerp(o.Alpha, snowAlbedo.a, snowAmount);\n o.Smoothness = lerp(o.Smoothness, snowSmoothAO.x, snowAmount);\n o.Occlusion = lerp(o.Occlusion, snowSmoothAO.y, snowAmount);\n o.Height = o.Alpha;\n o.Metallic *= (1.0-snowAmount);\n \n\n }\n #endif\n }\n\n \n\n\n\n\n\n \n void ChainSurfaceFunction(inout Surface l, inout ShaderData d)\n {\n Ext_SurfaceFunction0(l, d);\n Ext_SurfaceFunction1(l, d);\n Ext_SurfaceFunction2(l, d);\n Ext_SurfaceFunction3(l, d);\n // Ext_SurfaceFunction4(l, d);\n // Ext_SurfaceFunction5(l, d);\n // Ext_SurfaceFunction6(l, d);\n // Ext_SurfaceFunction7(l, d);\n // Ext_SurfaceFunction8(l, d);\n // Ext_SurfaceFunction9(l, d);\n\t\t // Ext_SurfaceFunction10(l, d);\n // Ext_SurfaceFunction11(l, d);\n // Ext_SurfaceFunction12(l, d);\n // Ext_SurfaceFunction13(l, d);\n // Ext_SurfaceFunction14(l, d);\n // Ext_SurfaceFunction15(l, d);\n // Ext_SurfaceFunction16(l, d);\n // Ext_SurfaceFunction17(l, d);\n // Ext_SurfaceFunction18(l, d);\n\t\t // Ext_SurfaceFunction19(l, d);\n // Ext_SurfaceFunction20(l, d);\n // Ext_SurfaceFunction21(l, d);\n // Ext_SurfaceFunction22(l, d);\n // Ext_SurfaceFunction23(l, d);\n // Ext_SurfaceFunction24(l, d);\n // Ext_SurfaceFunction25(l, d);\n // Ext_SurfaceFunction26(l, d);\n // Ext_SurfaceFunction27(l, d);\n // Ext_SurfaceFunction28(l, d);\n\t\t // Ext_SurfaceFunction29(l, d);\n }\n\n#if !_DECALSHADER\n\n void ChainModifyVertex(inout VertexData v, inout VertexToPixel v2p, float4 time)\n {\n ExtraV2F d;\n \n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n // due to motion vectors in HDRP, we need to use the last\n // time in certain spots. So if you are going to use _Time to adjust vertices,\n // you need to use this time or motion vectors will break. \n d.time = time;\n\n // Ext_ModifyVertex0(v, d);\n // Ext_ModifyVertex1(v, d);\n // Ext_ModifyVertex2(v, d);\n Ext_ModifyVertex3(v, d);\n // Ext_ModifyVertex4(v, d);\n // Ext_ModifyVertex5(v, d);\n // Ext_ModifyVertex6(v, d);\n // Ext_ModifyVertex7(v, d);\n // Ext_ModifyVertex8(v, d);\n // Ext_ModifyVertex9(v, d);\n // Ext_ModifyVertex10(v, d);\n // Ext_ModifyVertex11(v, d);\n // Ext_ModifyVertex12(v, d);\n // Ext_ModifyVertex13(v, d);\n // Ext_ModifyVertex14(v, d);\n // Ext_ModifyVertex15(v, d);\n // Ext_ModifyVertex16(v, d);\n // Ext_ModifyVertex17(v, d);\n // Ext_ModifyVertex18(v, d);\n // Ext_ModifyVertex19(v, d);\n // Ext_ModifyVertex20(v, d);\n // Ext_ModifyVertex21(v, d);\n // Ext_ModifyVertex22(v, d);\n // Ext_ModifyVertex23(v, d);\n // Ext_ModifyVertex24(v, d);\n // Ext_ModifyVertex25(v, d);\n // Ext_ModifyVertex26(v, d);\n // Ext_ModifyVertex27(v, d);\n // Ext_ModifyVertex28(v, d);\n // Ext_ModifyVertex29(v, d);\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainModifyTessellatedVertex(inout VertexData v, inout VertexToPixel v2p)\n {\n ExtraV2F d;\n ZERO_INITIALIZE(ExtraV2F, d);\n ZERO_INITIALIZE(Blackboard, d.blackboard);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = v2p.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = v2p.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = v2p.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = v2p.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = v2p.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = v2p.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = v2p.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = v2p.extraV2F7;\n // #endif\n\n\n // Ext_ModifyTessellatedVertex0(v, d);\n Ext_ModifyTessellatedVertex1(v, d);\n Ext_ModifyTessellatedVertex2(v, d);\n Ext_ModifyTessellatedVertex3(v, d);\n // Ext_ModifyTessellatedVertex4(v, d);\n // Ext_ModifyTessellatedVertex5(v, d);\n // Ext_ModifyTessellatedVertex6(v, d);\n // Ext_ModifyTessellatedVertex7(v, d);\n // Ext_ModifyTessellatedVertex8(v, d);\n // Ext_ModifyTessellatedVertex9(v, d);\n // Ext_ModifyTessellatedVertex10(v, d);\n // Ext_ModifyTessellatedVertex11(v, d);\n // Ext_ModifyTessellatedVertex12(v, d);\n // Ext_ModifyTessellatedVertex13(v, d);\n // Ext_ModifyTessellatedVertex14(v, d);\n // Ext_ModifyTessellatedVertex15(v, d);\n // Ext_ModifyTessellatedVertex16(v, d);\n // Ext_ModifyTessellatedVertex17(v, d);\n // Ext_ModifyTessellatedVertex18(v, d);\n // Ext_ModifyTessellatedVertex19(v, d);\n // Ext_ModifyTessellatedVertex20(v, d);\n // Ext_ModifyTessellatedVertex21(v, d);\n // Ext_ModifyTessellatedVertex22(v, d);\n // Ext_ModifyTessellatedVertex23(v, d);\n // Ext_ModifyTessellatedVertex24(v, d);\n // Ext_ModifyTessellatedVertex25(v, d);\n // Ext_ModifyTessellatedVertex26(v, d);\n // Ext_ModifyTessellatedVertex27(v, d);\n // Ext_ModifyTessellatedVertex28(v, d);\n // Ext_ModifyTessellatedVertex29(v, d);\n\n // #if %EXTRAV2F0REQUIREKEY%\n // v2p.extraV2F0 = d.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // v2p.extraV2F1 = d.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // v2p.extraV2F2 = d.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // v2p.extraV2F3 = d.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // v2p.extraV2F4 = d.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // v2p.extraV2F5 = d.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // v2p.extraV2F6 = d.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // v2p.extraV2F7 = d.extraV2F7;\n // #endif\n }\n\n void ChainFinalColorForward(inout Surface l, inout ShaderData d, inout half4 color)\n {\n // Ext_FinalColorForward0(l, d, color);\n // Ext_FinalColorForward1(l, d, color);\n // Ext_FinalColorForward2(l, d, color);\n // Ext_FinalColorForward3(l, d, color);\n // Ext_FinalColorForward4(l, d, color);\n // Ext_FinalColorForward5(l, d, color);\n // Ext_FinalColorForward6(l, d, color);\n // Ext_FinalColorForward7(l, d, color);\n // Ext_FinalColorForward8(l, d, color);\n // Ext_FinalColorForward9(l, d, color);\n // Ext_FinalColorForward10(l, d, color);\n // Ext_FinalColorForward11(l, d, color);\n // Ext_FinalColorForward12(l, d, color);\n // Ext_FinalColorForward13(l, d, color);\n // Ext_FinalColorForward14(l, d, color);\n // Ext_FinalColorForward15(l, d, color);\n // Ext_FinalColorForward16(l, d, color);\n // Ext_FinalColorForward17(l, d, color);\n // Ext_FinalColorForward18(l, d, color);\n // Ext_FinalColorForward19(l, d, color);\n // Ext_FinalColorForward20(l, d, color);\n // Ext_FinalColorForward21(l, d, color);\n // Ext_FinalColorForward22(l, d, color);\n // Ext_FinalColorForward23(l, d, color);\n // Ext_FinalColorForward24(l, d, color);\n // Ext_FinalColorForward25(l, d, color);\n // Ext_FinalColorForward26(l, d, color);\n // Ext_FinalColorForward27(l, d, color);\n // Ext_FinalColorForward28(l, d, color);\n // Ext_FinalColorForward29(l, d, color);\n }\n\n void ChainFinalGBufferStandard(inout Surface s, inout ShaderData d, inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 outEmission, inout half4 outShadowMask)\n {\n // Ext_FinalGBufferStandard0(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard1(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard2(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard3(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard4(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard5(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard6(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard7(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard8(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard9(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard10(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard11(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard12(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard13(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard14(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard15(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard16(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard17(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard18(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard19(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard20(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard21(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard22(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard23(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard24(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard25(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard26(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard27(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard28(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n // Ext_FinalGBufferStandard29(s, d, GBuffer0, GBuffer1, GBuffer2, outEmission, outShadowMask);\n }\n#endif\n\n\n \n\n\n#if _DECALSHADER\n\n ShaderData CreateShaderData(SurfaceDescriptionInputs IN)\n {\n ShaderData d = (ShaderData)0;\n d.TBNMatrix = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);\n d.worldSpaceNormal = IN.WorldSpaceNormal;\n d.worldSpaceTangent = IN.WorldSpaceTangent;\n\n d.worldSpacePosition = IN.WorldSpacePosition;\n d.texcoord0 = IN.uv0.xyxy;\n d.screenPos = IN.ScreenPosition;\n\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - d.worldSpacePosition);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(d.worldSpacePosition, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), d.worldSpaceTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenUV = (IN.ScreenPosition.xy / max(0.01, IN.ScreenPosition.w));\n #endif\n\n return d;\n }\n#else\n\n ShaderData CreateShaderData(VertexToPixel i\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n ShaderData d = (ShaderData)0;\n d.clipPos = i.pos;\n d.worldSpacePosition = i.worldPos;\n\n d.worldSpaceNormal = normalize(i.worldNormal);\n d.worldSpaceTangent.xyz = normalize(i.worldTangent.xyz);\n\n d.tangentSign = i.worldTangent.w * unity_WorldTransformParams.w;\n float3 bitangent = cross(d.worldSpaceTangent.xyz, d.worldSpaceNormal) * d.tangentSign;\n \n d.TBNMatrix = float3x3(d.worldSpaceTangent, -bitangent, d.worldSpaceNormal);\n d.worldSpaceViewDir = normalize(_WorldSpaceCameraPos - i.worldPos);\n\n d.tangentSpaceViewDir = mul(d.TBNMatrix, d.worldSpaceViewDir);\n d.texcoord0 = i.texcoord0;\n d.texcoord1 = i.texcoord1;\n // d.texcoord2 = i.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // d.texcoord3 = i.texcoord3;\n // #endif\n\n // d.isFrontFace = facing;\n // #if %VERTEXCOLORREQUIREKEY%\n d.vertexColor = i.vertexColor;\n // #endif\n\n // these rarely get used, so we back transform them. Usually will be stripped.\n #if _HDRP\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(GetCameraRelativePositionWS(i.worldPos), 1)).xyz;\n #else\n d.localSpacePosition = mul(GetWorldToObjectMatrix(), float4(i.worldPos, 1)).xyz;\n #endif\n d.localSpaceNormal = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldNormal));\n // d.localSpaceTangent = normalize(mul((float3x3)GetWorldToObjectMatrix(), i.worldTangent.xyz));\n\n #if _SNOWSPARKLES\n d.screenPos = i.screenPos;\n d.screenUV = (i.screenPos.xy / i.screenPos.w);\n #endif\n\n\n // #if %EXTRAV2F0REQUIREKEY%\n // d.extraV2F0 = i.extraV2F0;\n // #endif\n\n // #if %EXTRAV2F1REQUIREKEY%\n // d.extraV2F1 = i.extraV2F1;\n // #endif\n\n // #if %EXTRAV2F2REQUIREKEY%\n // d.extraV2F2 = i.extraV2F2;\n // #endif\n\n // #if %EXTRAV2F3REQUIREKEY%\n // d.extraV2F3 = i.extraV2F3;\n // #endif\n\n // #if %EXTRAV2F4REQUIREKEY%\n // d.extraV2F4 = i.extraV2F4;\n // #endif\n\n // #if %EXTRAV2F5REQUIREKEY%\n // d.extraV2F5 = i.extraV2F5;\n // #endif\n\n // #if %EXTRAV2F6REQUIREKEY%\n // d.extraV2F6 = i.extraV2F6;\n // #endif\n\n // #if %EXTRAV2F7REQUIREKEY%\n // d.extraV2F7 = i.extraV2F7;\n // #endif\n\n return d;\n }\n\n#endif\n\n \n\n#if (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)\n\n // This was not in constant buffer in original unity, so keep outiside. But should be in as ShaderRenderPass frequency\n float unity_OneOverOutputBoost;\n float unity_MaxOutputValue;\n\n CBUFFER_START(UnityMetaPass)\n // x = use uv1 as raster position\n // y = use uv2 as raster position\n bool4 unity_MetaVertexControl;\n\n // x = return albedo\n // y = return normal\n bool4 unity_MetaFragmentControl;\n CBUFFER_END\n\n VertexToPixel Vert(VertexData inputMesh)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n UNITY_SETUP_INSTANCE_ID(inputMesh);\n UNITY_TRANSFER_INSTANCE_ID(inputMesh, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n // Output UV coordinate in vertex shader\n float2 uv = float2(0.0, 0.0);\n\n if (unity_MetaVertexControl.x)\n {\n uv = inputMesh.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;\n }\n else if (unity_MetaVertexControl.y)\n {\n uv = inputMesh.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;\n }\n\n // OpenGL right now needs to actually use the incoming vertex position\n // so we create a fake dependency on it here that haven't any impact.\n output.pos = float4(uv * 2.0 - 1.0, inputMesh.vertex.z > 0 ? 1.0e-4 : 0.0, 1.0);\n\n output.worldPos = TransformObjectToWorld(inputMesh.vertex.xyz).xyz;\n\n // Normal is required for triplanar mapping\n output.worldNormal = TransformObjectToWorldNormal(inputMesh.normal);\n // Not required but assign to silent compiler warning\n output.worldTangent = float4(1.0, 0.0, 0.0, 0.0);\n\n output.texcoord0 = inputMesh.texcoord0;\n output.texcoord1 = inputMesh.texcoord1;\n output.texcoord2 = inputMesh.texcoord2;\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = inputMesh.texcoord3;\n // #endif\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = inputMesh.vertexColor;\n // #endif\n\n return output;\n }\n#else\n\n #if (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesMatrixDefsHDCamera.hlsl\"\n\n void MotionVectorPositionZBias(VertexToPixel input)\n {\n #if UNITY_REVERSED_Z\n input.pos.z -= unity_MotionVectorsParams.z * input.pos.w;\n #else\n input.pos.z += unity_MotionVectorsParams.z * input.pos.w;\n #endif\n }\n\n #endif\n\n VertexToPixel Vert(VertexData input)\n {\n VertexToPixel output;\n ZERO_INITIALIZE(VertexToPixel, output);\n\n UNITY_SETUP_INSTANCE_ID(input);\n UNITY_TRANSFER_INSTANCE_ID(input, output);\n UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);\n\n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n VertexData previousMesh = input;\n #endif\n\n ChainModifyVertex(input, output, _Time);\n\n // This return the camera relative position (if enable)\n float3 positionRWS = TransformObjectToWorld(input.vertex.xyz);\n float3 normalWS = TransformObjectToWorldNormal(input.normal);\n float4 tangentWS = float4(TransformObjectToWorldDir(input.tangent.xyz), input.tangent.w);\n\n\n output.worldPos = GetAbsolutePositionWS(positionRWS);\n output.pos = TransformWorldToHClip(positionRWS);\n output.worldNormal = normalWS;\n output.worldTangent = tangentWS;\n\n\n output.texcoord0 = input.texcoord0;\n output.texcoord1 = input.texcoord1;\n output.texcoord2 = input.texcoord2;\n\n // #if %TEXCOORD3REQUIREKEY%\n // output.texcoord3 = input.texcoord3;\n // #endif\n\n // #if %VERTEXCOLORREQUIREKEY%\n output.vertexColor = input.vertexColor;\n // #endif\n\n #if _SNOWSPARKLES\n output.screenPos = ComputeScreenPos(output.pos, _ProjectionParams.x);\n #endif\n \n #if _HDRP && (_PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))\n\n #if !defined(TESSELLATION_ON)\n MotionVectorPositionZBias(output);\n #endif\n\n output.motionVectorCS = mul(UNITY_MATRIX_UNJITTERED_VP, float4(positionRWS.xyz, 1.0));\n // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled\n bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;\n if (forceNoMotion)\n {\n output.previousPositionCS = float4(0.0, 0.0, 0.0, 1.0);\n }\n else\n {\n bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target\n\n float3 effectivePositionOS = (hasDeformation ? previousMesh.previousPositionOS : previousMesh.vertex.xyz);\n #if defined(_ADD_PRECOMPUTED_VELOCITY)\n effectivePositionOS -= input.precomputedVelocity;\n #endif\n\n previousMesh.vertex = float4(effectivePositionOS, 1);\n VertexToPixel dummy = (VertexToPixel)0;\n \n\n ChainModifyVertex(previousMesh, dummy, _LastTimeParameters);\n\n // we might need this for skinned objects?\n //float3 normalWS = TransformPreviousObjectToWorldNormal(input.normal).xyz;\n float3 previousPositionRWS = TransformPreviousObjectToWorld(previousMesh.vertex.xyz);\n\n #ifdef _WRITE_TRANSPARENT_MOTION_VECTOR\n if (_TransparentCameraOnlyMotionVectors > 0)\n {\n previousPositionRWS = positionRWS.xyz;\n }\n #endif // _WRITE_TRANSPARENT_MOTION_VECTOR\n\n output.previousPositionCS = mul(UNITY_MATRIX_PREV_VP, float4(previousPositionRWS, 1.0));\n }\n #endif // _HDRP && _PASSMOTIONVECTOR || ((_PASSFORWARD || _PASSUNLIT) && defined(_WRITE_TRANSPARENT_MOTION_VECTOR))\n\n\n return output;\n }\n\n\n#endif\n\n\n\n \n\n \n\n #if (defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS)) || defined(WRITE_RENDERING_LAYER)\n #include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl\"\n #endif\n\n FragInputs BuildFragInputs(VertexToPixel input)\n {\n UNITY_SETUP_INSTANCE_ID(input);\n FragInputs output;\n ZERO_INITIALIZE(FragInputs, output);\n \n // Init to some default value to make the computer quiet (else it output 'divide by zero' warning even if value is not used).\n // TODO: this is a really poor workaround, but the variable is used in a bunch of places\n // to compute normals which are then passed on elsewhere to compute other values...\n output.tangentToWorld = k_identity3x3;\n output.positionSS = input.pos; // input.positionCS is SV_Position\n // BETTER SHADERS: because we transform world position into actual world space for things like\n // triplanar, etc, we have to back transform it here for lighting\n output.positionRWS = GetCameraRelativePositionWS(input.worldPos);\n output.tangentToWorld = BuildTangentToWorld(input.worldTangent, input.worldNormal);\n output.texCoord0 = input.texcoord0;\n output.texCoord1 = input.texcoord1;\n output.texCoord2 = input.texcoord2;\n \n return output;\n }\n\n#if UNITY_VERSION > UNITY_2022_3_12\n void ApplyDecalAndGetNormal(FragInputs fragInputs, PositionInputs posInput, Surface surfaceDescription, float3 normalTS,\n inout SurfaceData surfaceData)\n {\n float3 doubleSidedConstants = GetDoubleSidedConstants();\n \n #ifdef DECAL_NORMAL_BLENDING\n // SG nodes don't ouptut surface gradients, so if decals require surf grad blending, we have to convert\n // the normal to gradient before applying the decal. We then have to resolve the gradient back to world space\n normalTS = SurfaceGradientFromTangentSpaceNormalAndFromTBN(normalTS,\n fragInputs.tangentToWorld[0], fragInputs.tangentToWorld[1]);\n \n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, fragInputs.tangentToWorld[2], normalTS);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n \n GetNormalWS_SG(fragInputs, normalTS, surfaceData.normalWS, doubleSidedConstants);\n #else\n // normal delivered to master node\n \n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n \n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceNormal(decalSurfaceData, surfaceData.normalWS.xyz);\n ApplyDecalToSurfaceDataNoNormal(decalSurfaceData, surfaceData);\n }\n #endif\n #endif\n }\n#endif\n\n void BuildSurfaceData(FragInputs fragInputs, inout Surface surfaceDescription, float3 V, PositionInputs posInput, out SurfaceData surfaceData, out float3 bentNormalWS)\n {\n // setup defaults -- these are used if the graph doesn't output a value\n ZERO_INITIALIZE(SurfaceData, surfaceData);\n \n // specularOcclusion need to be init ahead of decal to quiet the compiler that modify the SurfaceData struct\n // however specularOcclusion can come from the graph, so need to be init here so it can be override.\n surfaceData.specularOcclusion = 1.0;\n\n // copy across graph values, if defined\n surfaceData.baseColor = surfaceDescription.Albedo;\n surfaceData.perceptualSmoothness = surfaceDescription.Smoothness;\n surfaceData.ambientOcclusion = surfaceDescription.Occlusion;\n surfaceData.specularOcclusion = surfaceDescription.SpecularOcclusion;\n surfaceData.metallic = surfaceDescription.Metallic;\n surfaceData.subsurfaceMask = surfaceDescription.SubsurfaceMask;\n surfaceData.thickness = surfaceDescription.Thickness;\n surfaceData.diffusionProfileHash = asuint(surfaceDescription.DiffusionProfileHash);\n #if _USESPECULAR\n surfaceData.specularColor = surfaceDescription.Specular;\n #endif\n surfaceData.coatMask = surfaceDescription.CoatMask;\n surfaceData.anisotropy = surfaceDescription.Anisotropy;\n surfaceData.iridescenceMask = surfaceDescription.IridescenceMask;\n surfaceData.iridescenceThickness = surfaceDescription.IridescenceThickness;\n\n\n\n #if defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE) || defined(_REFRACTION_THIN)\n if (_EnableSSRefraction)\n {\n surfaceData.transmittanceMask = (1.0 - surfaceDescription.Alpha);\n surfaceDescription.Alpha = 1.0;\n }\n else\n {\n surfaceData.ior = surfaceDescription.ior;\n surfaceData.transmittanceColor = surfaceDescription.transmittanceColor;\n surfaceData.atDistance = surfaceDescription.atDistance;\n surfaceData.transmittanceMask = surfaceDescription.transmittanceMask;\n surfaceDescription.Alpha = 1.0;\n }\n #else\n surfaceData.ior = 1.0;\n surfaceData.transmittanceColor = float3(1.0, 1.0, 1.0);\n surfaceData.atDistance = 1.0;\n surfaceData.transmittanceMask = 0.0;\n #endif\n\n \n\n // These static material feature allow compile time optimization\n surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;\n #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING;\n #endif\n \n #ifdef _MATERIAL_FEATURE_TRANSMISSION\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION;\n #endif\n \n #ifdef _MATERIAL_FEATURE_ANISOTROPY\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_ANISOTROPY;\n surfaceData.normalWS = float3(0, 1, 0);\n #endif\n \n #ifdef _MATERIAL_FEATURE_IRIDESCENCE\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_IRIDESCENCE;\n #endif\n \n #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SPECULAR_COLOR;\n #endif\n \n #if defined(_MATERIAL_FEATURE_CLEAR_COAT) || _CLEARCOAT\n surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_CLEAR_COAT;\n #endif\n \n #if defined (_MATERIAL_FEATURE_SPECULAR_COLOR) && defined (_ENERGY_CONSERVING_SPECULAR)\n // Require to have setup baseColor\n // Reproduce the energy conservation done in legacy Unity. Not ideal but better for compatibility and users can unchek it\n surfaceData.baseColor *= (1.0 - Max3(surfaceData.specularColor.r, surfaceData.specularColor.g, surfaceData.specularColor.b));\n #endif\n\n float3 normalTS = surfaceDescription.Normal;\n #if !_WORLDSPACENORMAL\n surfaceData.normalWS = mul(surfaceDescription.Normal, fragInputs.tangentToWorld);\n #else\n normalTS = mul(fragInputs.tangentToWorld, surfaceDescription.Normal);\n surfaceData.normalWS = surfaceDescription.Normal;\n #endif\n\n\n #if UNITY_VERSION > UNITY_2022_3_12\n ApplyDecalAndGetNormal(fragInputs, posInput, surfaceDescription, normalTS, surfaceData);\n #else\n #ifdef DECAL_NORMAL_BLENDING\n #if HAVE_DECALS\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n if (_EnableDecals)\n {\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData, normalTS);\n }\n #endif\n #else\n #if HAVE_DECALS\n if (_EnableDecals)\n {\n float alpha = 1.0;\n alpha = surfaceDescription.Alpha;\n // Both uses and modifies 'surfaceData.normalWS'.\n DecalSurfaceData decalSurfaceData = GetDecalSurfaceData(posInput, fragInputs, alpha);\n ApplyDecalToSurfaceData(decalSurfaceData, fragInputs.tangentToWorld[2], surfaceData);\n }\n #endif\n #endif\n #endif\n\n \n\n surfaceData.geomNormalWS = fragInputs.tangentToWorld[2];\n \n surfaceData.tangentWS = normalize(fragInputs.tangentToWorld[0].xyz); // The tangent is not normalize in tangentToWorld for mikkt. TODO: Check if it expected that we normalize with Morten. Tag: SURFACE_GRADIENT\n\n\n bentNormalWS = surfaceData.normalWS;\n \n surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);\n \n #ifdef DEBUG_DISPLAY\n if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)\n {\n // TODO: need to update mip info\n surfaceData.metallic = 0;\n }\n \n // We need to call ApplyDebugToSurfaceData after filling the surfarcedata and before filling builtinData\n // as it can modify attribute use for static lighting\n ApplyDebugToSurfaceData(fragInputs.tangentToWorld, surfaceData);\n #endif\n \n // By default we use the ambient occlusion with Tri-ace trick (apply outside) for specular occlusion.\n // If user provide bent normal then we process a better term\n #if defined(_SPECULAR_OCCLUSION_CUSTOM)\n // Just use the value passed through via the slot (not active otherwise)\n #elif defined(_SPECULAR_OCCLUSION_FROM_AO_BENT_NORMAL)\n // If we have bent normal and ambient occlusion, process a specular occlusion\n surfaceData.specularOcclusion = GetSpecularOcclusionFromBentAO(V, bentNormalWS, surfaceData.normalWS, surfaceData.ambientOcclusion, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));\n #elif defined(_AMBIENT_OCCLUSION) && defined(_SPECULAR_OCCLUSION_FROM_AO)\n surfaceData.specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(dot(surfaceData.normalWS, V)), surfaceData.ambientOcclusion, PerceptualSmoothnessToRoughness(surfaceData.perceptualSmoothness));\n #endif\n \n #if defined(_ENABLE_GEOMETRIC_SPECULAR_AA) && !defined(SHADER_STAGE_RAY_TRACING)\n surfaceData.perceptualSmoothness = GeometricNormalFiltering(surfaceData.perceptualSmoothness, fragInputs.tangentToWorld[2], surfaceDescription.SpecularAAScreenSpaceVariance, surfaceDescription.SpecularAAThreshold);\n #endif\n }\n \n void GetSurfaceAndBuiltinData(VertexToPixel m2ps, FragInputs fragInputs, float3 V, inout PositionInputs posInput,\n out SurfaceData surfaceData, out BuiltinData builtinData, inout Surface l, inout ShaderData d\n #if NEED_FACING\n , bool facing\n #endif\n )\n {\n // Removed since crossfade does not work, probably needs extra material setup. \n //#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)\n // #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group\n // LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);\n // #endif\n //#endif\n\n\n\n\n d = CreateShaderData(m2ps\n #if NEED_FACING\n , facing\n #endif\n );\n\n l = (Surface)0;\n\n l.Albedo = half3(0.5, 0.5, 0.5);\n l.Normal = float3(0,0,1);\n l.Occlusion = 1;\n l.Alpha = 1;\n l.SpecularOcclusion = 1;\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n l.outputDepth = d.clipPos.z;\n #endif\n\n ChainSurfaceFunction(l, d);\n\n #if !defined(SHADER_STAGE_RAY_TRACING) && defined(_DEPTHOFFSET_ON)\n posInput.deviceDepth = l.outputDepth;\n #endif\n\n #if _UNLIT\n //l.Emission = l.Albedo;\n //l.Albedo = 0;\n l.Normal = half3(0,0,1);\n l.Occlusion = 1;\n l.Metallic = 0;\n l.Specular = 0;\n #endif\n\n surfaceData.geomNormalWS = d.worldSpaceNormal;\n surfaceData.tangentWS = d.worldSpaceTangent;\n fragInputs.tangentToWorld = d.TBNMatrix;\n\n float3 bentNormalWS;\n\n BuildSurfaceData(fragInputs, l, V, posInput, surfaceData, bentNormalWS);\n\n\n float4 lightmapTexCoord1 = fragInputs.texCoord1;\n float4 lightmapTexCoord2 = fragInputs.texCoord2;\n //#ifdef FRAG_INPUTS_USE_TEXCOORD1\n // float4 lightmapTexCoord1 = fragInputs.texCoord1;\n // #else\n // float4 lightmapTexCoord1 = float4(0,0,0,0);\n // #endif\n \n // #ifdef FRAG_INPUTS_USE_TEXCOORD2\n // float4 lightmapTexCoord2 = fragInputs.texCoord2;\n // #else\n // float4 lightmapTexCoord2 = float4(0,0,0,0);\n // #endif\n\n\n InitBuiltinData(posInput, l.Alpha, bentNormalWS, -d.worldSpaceNormal, lightmapTexCoord1, lightmapTexCoord2, builtinData);\n\n \n\n builtinData.emissiveColor = l.Emission;\n\n #if defined(_OVERRIDE_BAKEDGI)\n builtinData.bakeDiffuseLighting = l.DiffuseGI;\n builtinData.backBakeDiffuseLighting = l.BackDiffuseGI;\n builtinData.emissiveColor += l.SpecularGI;\n #endif\n\n #if defined(_OVERRIDE_SHADOWMASK)\n builtinData.shadowMask0 = l.ShadowMask.x;\n builtinData.shadowMask1 = l.ShadowMask.y;\n builtinData.shadowMask2 = l.ShadowMask.z;\n builtinData.shadowMask3 = l.ShadowMask.w;\n #endif\n\n #ifdef UNITY_VIRTUAL_TEXTURING\n //builtinData.vtPackedFeedback = surfaceData.VTPackedFeedback;\n #endif\n\n #if (SHADERPASS == SHADERPASS_DISTORTION)\n builtinData.distortion = surfaceData.Distortion;\n builtinData.distortionBlur = surfaceData.DistortionBlur;\n #endif\n\n #ifndef SHADER_UNLIT\n // PostInitBuiltinData call ApplyDebugToBuiltinData\n PostInitBuiltinData(V, posInput, surfaceData, builtinData);\n #else\n ApplyDebugToBuiltinData(builtinData);\n #endif\n \n RAY_TRACING_OPTIONAL_ALPHA_TEST_PASS\n }\n\n\n\n#define DEBUG_DISPLAY\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl\"\n#include \"Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/FullScreenDebug.hlsl\"\n\n #if !defined(_DEPTHOFFSET_ON)\n [earlydepthstencil] // quad overshading debug mode writes to UAV\n #endif\n void Frag(VertexToPixel v2f\n #if NEED_FACING\n , bool facing : SV_IsFrontFace\n #endif\n )\n {\n UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v2f);\n FragInputs input = BuildFragInputs(v2f);\n\n PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz);\n\n #ifdef PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER\n if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_QUAD_OVERDRAW)\n {\n IncrementQuadOverdrawCounter(posInput.positionSS.xy, input.primitiveID);\n }\n #endif\n }\n\n ENDHLSL\n }\n\n \n\n\n\n\n\n\n\n\n\n\n \n }\n\n \n \n CustomEditor \"JBooth.Road.RoadMaterialEditor\"\n}\n"}],"betterShader":{"fileID":-6465566751694194690,"guid":"5866ef8b7b6254769b71f3f2d7c4fa18","type":3},"betterShaderPath":"Packages/com.jbooth.microverse.roads/Scripts/Shaders/BetterShadersSource/ProceduralRoad.stackedshader","optionOverrides":{"shaderName":"MicroVerse/Road/RoadLit","useCustomEditor":true,"customEditor":"JBooth.Road.RoadMaterialEditor","fallback":{"instanceID":0}}}}