#if _DISPLACEMENTDAMPENING TEXTURE2D(_DisplacementDampening); #endif #if _MESHCOMBINEDHEIGHT || _MESHCOMBINEDPACKEDMAP float SampleMeshCombinedTess(half h, half4 heightWeights, Config config, float mipLevel) { float stAlpha = 1; if (config.uv0.z == _MeshAlphaIndex) stAlpha = 1 - heightWeights.x; else if (config.uv1.z == _MeshAlphaIndex) stAlpha = 1 - heightWeights.y; else if (config.uv2.z == _MeshAlphaIndex) stAlpha = 1 - heightWeights.z; else if (config.uv3.z == _MeshAlphaIndex) stAlpha = 1 - heightWeights.w; float2 stuv = config.uv * _StandardUVScaleOffset.xy + _StandardUVScaleOffset.zw; #if _MESHCOMBINEDPACKEDMAP half standardHeight = SAMPLE_TEXTURE2D_LOD(_StandardPackedMap, sampler_StandardDiffuse, stuv, mipLevel).b; #elif _MESHCOMBINEDHEIGHT half standardHeight = SAMPLE_TEXTURE2D_LOD(_StandardHeight, sampler_StandardDiffuse, stuv, mipLevel).g; #endif // offset standardHeight += _MeshCombineTessOffset; // weight standardHeight *= (1-_MeshCombineTessBlend); h *= _MeshCombineTessBlend; h *= stAlpha; return standardHeight + h; } #endif #if _DISTANCERESAMPLE void DistanceResampleLOD(inout half oalbedo0, inout half oalbedo1, Config config, TriplanarConfig tc, half4 fxLevels, float3 worldPos, half4 weights, float3 worldNormalVertex) { float distanceBlend = 0; #if _DISTANCERESAMPLENOISE #if _TRIPLANAR distanceBlend = _DistanceResampleConstant + FBM3D(worldPos * _DistanceResampleNoiseParams.x) * _DistanceResampleNoiseParams.y; #else distanceBlend = _DistanceResampleConstant + FBM2D(config.uv * _DistanceResampleNoiseParams.x) * _DistanceResampleNoiseParams.y; #endif // triplanar #elif _DISTANCERESAMPLENOFADE distanceBlend = _DistanceResampleConstant; #endif float dblend0 = distanceBlend; float dblend1 = distanceBlend; config.uv0.xy *= _ResampleDistanceParams.xx; config.uv1.xy *= _ResampleDistanceParams.xx; half albedo0; half albedo1; half4 mipLevel = _TessData1.z; #if _PERTEXTESSMIPLEVEL SAMPLE_PER_TEX(perTexMipLevel, 4.5, config, half4(1.0, 0.0, 0, 0.0)); mipLevel.x = perTexMipLevel0.a; mipLevel.y = perTexMipLevel1.a; mipLevel.z = perTexMipLevel2.a; mipLevel.w = perTexMipLevel3.a; #endif #if _PERTEXDISTANCERESAMPLESTRENGTH SAMPLE_PER_TEX(strs, 4.5, config, half4(1.0, 1.0, 1.0, 0.0)); dblend0 *= strs0.b; dblend1 *= strs1.b; #endif #if _STREAMS || _PUDDLES || _LAVA half fac = 1.0 - min(fxLevels.y + fxLevels.z + fxLevels.w, 1.0f); dblend0 *= fac; dblend1 *= fac; #endif #if _TRIPLANAR #if _BRANCHSAMPLES UNITY_BRANCH if (dblend0 > 0) #endif { #if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3) half a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[0], config.cluster0, mipLevel.x).a; half a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[1], config.cluster0, mipLevel.x).a; half a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[2], config.cluster0, mipLevel.x).a; #else half a0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[0], mipLevel.x).a; half a1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[1], mipLevel.x).a; half a2 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[2], mipLevel.x).a; #endif albedo0 = a0 * tc.pN0.x + a1 * tc.pN0.y + a2 * tc.pN0.z; } #if _BRANCHSAMPLES UNITY_BRANCH if (dblend1 * weights.y > 0) #endif { #if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3) half a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[0], config.cluster1, mipLevel.y).a; half a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[1], config.cluster1, mipLevel.y).a; half a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[2], config.cluster1, mipLevel.y).a; #else half a0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[0], mipLevel.y).a; half a1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[1], mipLevel.y).a; half a2 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[2], mipLevel.y).a; #endif albedo1 = a0 * tc.pN1.x + a1 * tc.pN1.y + a2 * tc.pN1.z; } #else #if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3) #if _BRANCHSAMPLES UNITY_BRANCH if (dblend0 > 0) #endif { albedo0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv0, config.cluster0, mipLevel.x).a; } #if _BRANCHSAMPLES UNITY_BRANCH if (dblend1 * weights.y > 0) #endif { albedo1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv1, config.cluster1, mipLevel.y).a; } #else #if _BRANCHSAMPLES UNITY_BRANCH if (dblend0 > 0) #endif { albedo0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, config.uv0, mipLevel.x).a; } #if _BRANCHSAMPLES UNITY_BRANCH if (dblend1 * weights.y > 0) #endif { albedo1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, config.uv1, mipLevel.y).a; } #endif #endif #if _DISTANCERESAMPLEHEIGHTBLEND dblend0 = HeightBlend(oalbedo0, albedo0, dblend0, _Contrast); dblend1 = HeightBlend(oalbedo1, albedo1, dblend1, _Contrast); #endif oalbedo0 = lerp(oalbedo0, albedo0, dblend0); oalbedo1 = lerp(oalbedo1, albedo1, dblend1); } #endif void SampleSplatsLOD(float2 controlUV, inout fixed4 w0, inout fixed4 w1, inout fixed4 w2, inout fixed4 w3, inout fixed4 w4, inout fixed4 w5, inout fixed4 w6, inout fixed4 w7) { #if _CUSTOMSPLATTEXTURES #if !_MICROMESH controlUV = (controlUV * (_CustomControl0_TexelSize.zw - 1.0f) + 0.5f) * _CustomControl0_TexelSize.xy; #endif #if _CONTROLNOISEUV controlUV += (SAMPLE_TEXTURE2D_LOD(_NoiseUV, sampler_Diffuse, controlUV * _CustomControl0_TexelSize.zw * 0.2 * _NoiseUVParams.x, 0).ga - 0.5) * _CustomControl0_TexelSize.xy * _NoiseUVParams.y; #endif w0 = SAMPLE_TEXTURE2D_LOD(_CustomControl0, shared_linear_clamp_sampler, controlUV.xy, 0); #if !_MAX4TEXTURES w1 = SAMPLE_TEXTURE2D_LOD(_CustomControl1, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if !_MAX4TEXTURES && !_MAX8TEXTURES w2 = SAMPLE_TEXTURE2D_LOD(_CustomControl2, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if !_MAX4TEXTURES && !_MAX8TEXTURES && !_MAX12TEXTURES w3 = SAMPLE_TEXTURE2D_LOD(_CustomControl3, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX20TEXTURES || _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES w4 = SAMPLE_TEXTURE2D_LOD(_CustomControl4, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES w5 = SAMPLE_TEXTURE2D_LOD(_CustomControl5, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX28TEXTURES || _MAX32TEXTURES w6 = SAMPLE_TEXTURE2D_LOD(_CustomControl6, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX32TEXTURES w7 = SAMPLE_TEXTURE2D_LOD(_CustomControl7, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #else #if !_MICROMESH controlUV = (controlUV * (_Control0_TexelSize.zw - 1.0f) + 0.5f) * _Control0_TexelSize.xy; #endif #if _CONTROLNOISEUV controlUV += (SAMPLE_TEXTURE2D_LOD(_NoiseUV, sampler_Diffuse, controlUV * _Control0_TexelSize.zw * 0.2 * _NoiseUVParams.x, 0).ga - 0.5) * _Control0_TexelSize.xy * _NoiseUVParams.y; #endif w0 = SAMPLE_TEXTURE2D_LOD(_Control0, shared_linear_clamp_sampler, controlUV.xy, 0); #if !_MAX4TEXTURES w1 = SAMPLE_TEXTURE2D_LOD(_Control1, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if !_MAX4TEXTURES && !_MAX8TEXTURES w2 = SAMPLE_TEXTURE2D_LOD(_Control2, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if !_MAX4TEXTURES && !_MAX8TEXTURES && !_MAX12TEXTURES w3 = SAMPLE_TEXTURE2D_LOD(_Control3, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX20TEXTURES || _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES w4 = SAMPLE_TEXTURE2D_LOD(_Control4, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES w5 = SAMPLE_TEXTURE2D_LOD(_Control5, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX28TEXTURES || _MAX32TEXTURES w6 = SAMPLE_TEXTURE2D_LOD(_Control6, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #if _MAX32TEXTURES w7 = SAMPLE_TEXTURE2D_LOD(_Control7, shared_linear_clamp_sampler, controlUV.xy, 0); #endif #endif } float3 OffsetVertex(VertexData v, ExtraV2F ex) { float2 texcoord = v.texcoord0.xy; float3 vertex = v.vertex.xyz; float3 normal = v.normal; #if _MICROVERSEPREVIEW float4 recipSize = _TerrainHeightmapTexture_TexelSize; recipSize.zw = (1.0f / (_TerrainHeightmapTexture_TexelSize.zw-1)); float2 sampleCoords = (texcoord / recipSize.zw + 0.5f) * recipSize.xy; float height = UnpackHeightmap(SAMPLE_TEXTURE2D_LOD(_TerrainHeightmapTexture, shared_linear_clamp_sampler, sampleCoords, 0)); return float3(0,1,0) * height * _TerrainHeight * 2; #elif (defined(UNITY_INSTANCING_ENABLED) && _MICROTERRAIN && !_TERRAINBLENDABLESHADER) float2 sampleCoords = (texcoord.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy; normal = normalize(SAMPLE_TEXTURE2D_LOD(_TerrainNormalmapTexture, shared_linear_clamp_sampler, sampleCoords, 0).xyz * 2 - 1); #elif _PERPIXNORMAL && (_MICROTERRAIN || _MICROMESHTERRAIN) && !_TERRAINBLENDABLESHADER float2 sampleCoords = (texcoord.xy * _PerPixelNormal_TexelSize.zw + 0.5f) * _PerPixelNormal_TexelSize.xy; normal = normalize(SAMPLE_TEXTURE2D_LOD(_PerPixelNormal, shared_linear_clamp_sampler, sampleCoords, 0).xyz * 2 - 1); #endif float2 controlUV = v.texcoord0.xy; #if _MICROMESH controlUV = InverseLerp(_UVMeshRange.xy, _UVMeshRange.zw, controlUV); #endif half4 weights; #if _HDRP || _URP float3 worldPos = GetAbsolutePositionWS(TransformObjectToWorld(vertex.xyz)); #else float3 worldPos = TransformObjectToWorld(vertex).xyz; #endif #if _FORCELOCALSPACE worldPos = v.vertex; #endif float3 worldNormal = float3(0,0,1); #if _SNOW || _TRIPLANAR worldNormal = UnityObjectToWorldNormal(normal); #endif Config config = (Config)0; half4 mipLevel = _TessData1.z; fixed4 w0 = fixed4(1,0,0,0); fixed4 w1 = 0; fixed4 w2 = 0; fixed4 w3 = 0; fixed4 w4 = 0; fixed4 w5 = 0; fixed4 w6 = 0; fixed4 w7 = 0; DecalOutput decalOutput = (DecalOutput)0; #if _DECAL_TESS || _DECAL_SPLATS decalOutput = DoDecalsTess(texcoord, worldPos, 0, normal); #endif #if _MICRODIGGERMESH Input inp = (Input)0; UnpackVertexMesh(inp, ex); DiggerSetup(inp, weights, texcoord, config, worldPos, decalOutput); #elif _MEGASPLAT Input inp = (Input)0; UnpackMegaSplat(v, inp, ex); MegaSplatVertexSetup(inp, weights, texcoord, config, worldPos, decalOutput); #elif _MEGASPLATTEXTURE MegaSplatTextureSetup(controlUV, weights, texcoord.xy, config, worldPos, decalOutput); #elif _MEGASPLATTEXTURE && _PROCEDURALTEXTURE && !_DISABLESPLATMAPS && _PROCEDURALBLENDSPLATS MegaSplatTextureSetup(controlUV, weights, texcoord.xy, config, worldPos, decalOutput); float3 up = float3(0,1,0); float3 procNormal = normal; float height = worldPos.y; Input i = (Input)0; ProceduralSetup(i, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput); #elif _MICROVERTEXMESH || _MICRODIGGERMESH Input inp = (Input)0; UnpackVertexMesh(inp, ex); VertexSetup(inp, weights, texcoord, config, worldPos, decalOutput); #elif _PROCEDURALTEXTURE && !_DISABLESPLATMAPS && _PROCEDURALBLENDSPLATS SampleSplatsLOD(controlUV, w0, w1, w2, w3, w4, w5, w6, w7); Setup(weights, texcoord.xy, config, w0, w1, w2, w3, w4, w5, w6, w7, worldPos, decalOutput); float3 up = float3(0,1,0); float3 procNormal = normal; float height = worldPos.y; Input i = (Input)0; ProceduralSetup(i, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput); #elif _PROCEDURALTEXTURE && !_DISABLESPLATMAPS float3 up = float3(0,1,0); float3 procNormal = normal; float height = worldPos.y; Input input = (Input)0; ProceduralSetup(input, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput); #elif !_DISABLESPLATMAPS SampleSplatsLOD(controlUV, w0, w1, w2, w3, w4, w5, w6, w7); Setup(weights, texcoord.xy, config, w0, w1, w2, w3, w4, w5, w6, w7, worldPos, decalOutput); #endif // _DISABLESPLATMAPS #if _SLOPETEXTURE SlopeTexture(config, weights, normal); #endif #if _PERTEXTESSMIPLEVEL && !_DISABLESPLATMAPS SAMPLE_PER_TEX(perTexMipLevel, 4.5, config, half4(1.0, 0.0, 0, 0.0)); mipLevel.x = perTexMipLevel0.a; mipLevel.y = perTexMipLevel1.a; mipLevel.z = perTexMipLevel2.a; mipLevel.w = perTexMipLevel3.a; #endif #if _PERTEXCURVEWEIGHT SAMPLE_PER_TEX(ptCurveWeight, 19.5, config, half4(0.5,1,1,1)); weights.x = smoothstep(0.5 - ptCurveWeight0.r, 0.5 + ptCurveWeight0.r, weights.x); weights.y = smoothstep(0.5 - ptCurveWeight1.r, 0.5 + ptCurveWeight1.r, weights.y); weights.z = smoothstep(0.5 - ptCurveWeight2.r, 0.5 + ptCurveWeight2.r, weights.z); weights.w = smoothstep(0.5 - ptCurveWeight3.r, 0.5 + ptCurveWeight3.r, weights.w); weights = TotalOne(weights); #endif float traxBuffer = 0; #if _SNOWFOOTSTEPS || _TRAXSINGLE || _TRAXARRAY || _TRAXNOTEXTURE traxBuffer = SampleTraxBufferLOD(worldPos, normal, 1); #endif fixed4 levelFx = 0; #if _PUDDLES || _STREAMS || _LAVA || _WETNESSMASKSNOW #if _MICROMESH levelFx = SampleFXLevelsLOD(controlUV.xy, traxBuffer); #else levelFx = SampleFXLevelsLOD(texcoord.xy, traxBuffer); #endif #endif // uvScale before anything #if _PERTEXUVSCALEOFFSET && !_TRIPLANAR && !_DISABLESPLATMAPS SAMPLE_PER_TEX(ptUVScale, 0.5, config, half4(1,1,0,0)); config.uv0.xy = config.uv0.xy * ptUVScale0.rg + ptUVScale0.ba; config.uv1.xy = config.uv1.xy * ptUVScale1.rg + ptUVScale1.ba; #if !_MAX2LAYER config.uv2.xy = config.uv2.xy * ptUVScale2.rg + ptUVScale2.ba; #endif #if !_MAX3LAYER || !_MAX2LAYER config.uv3.xy = config.uv3.xy * ptUVScale3.rg + ptUVScale3.ba; #endif #endif #if _PERTEXUVROTATION && !_TRIPLANAR && !_DISABLESPLATMAPS SAMPLE_PER_TEX(ptUVRot, 16.5, config, half4(0,0,0,0)); config.uv0.xy = RotateUV(config.uv0.xy, ptUVRot0.x); config.uv1.xy = RotateUV(config.uv1.xy, ptUVRot1.x); #if !_MAX2LAYER config.uv2.xy = RotateUV(config.uv2.xy, ptUVRot2.x); #endif #if !_MAX3LAYER || !_MAX2LAYER config.uv3.xy = RotateUV(config.uv3.xy, ptUVRot0.x); #endif #endif TriplanarConfig tc = (TriplanarConfig)0; UNITY_INITIALIZE_OUTPUT(TriplanarConfig,tc); #if _TRIPLANAR && !_DISABLESPLATMAPS MIPFORMAT a = INITMIPFORMAT MIPFORMAT b = INITMIPFORMAT MIPFORMAT c = INITMIPFORMAT MIPFORMAT d = INITMIPFORMAT PrepTriplanarDisplace(v.texcoord0, worldNormal, worldPos, config, tc, weights, a, b, c, d); #endif #if _TEXTURECLUSTER2 || _TEXTURECLUSTER3 && !_DISABLESPLATMAPS PrepClustersDisplace(config.uv, config, worldPos, worldNormal); #endif half albedo0 = 0; half albedo1 = 0; half albedo2 = 0; half albedo3 = 0; #if !_DISABLESPLATMAPS #if _TRIPLANAR half4 contrasts = _Contrast.xxxx; #if _PERTEXTRIPLANARCONTRAST SAMPLE_PER_TEX(ptc, 5.5, config, half4(1,0.5,0,0)); contrasts = half4(ptc0.y, ptc1.y, ptc2.y, ptc3.y); #endif { half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[0], config.cluster0, mipLevel.x); half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[1], config.cluster0, mipLevel.x); half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[2], config.cluster0, mipLevel.x); half3 bf = tc.pN0; #if _TRIPLANARHEIGHTBLEND bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN0, contrasts.x); tc.pN0 = bf; #endif albedo0 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z; } #if _BRANCHSAMPLES UNITY_BRANCH if (weights.y > 0) #endif { half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[0], config.cluster1, mipLevel.y); half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[1], config.cluster1, mipLevel.y); half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[2], config.cluster1, mipLevel.y); half3 bf = tc.pN1; #if _TRIPLANARHEIGHTBLEND bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN1, contrasts.x); tc.pN1 = bf; #endif albedo1 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z; } #if !_MAX2LAYER #if _BRANCHSAMPLES UNITY_BRANCH if (weights.z > 0) #endif { half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[0], config.cluster2, mipLevel.z); half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[1], config.cluster2, mipLevel.z); half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[2], config.cluster2, mipLevel.z); half3 bf = tc.pN2; #if _TRIPLANARHEIGHTBLEND bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN2, contrasts.x); tc.pN2 = bf; #endif albedo2 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z; } #endif #if !_MAX3LAYER || !_MAX2LAYER #if _BRANCHSAMPLES UNITY_BRANCH if (weights.w > 0) #endif { half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[0], config.cluster3, mipLevel.w); half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[1], config.cluster3, mipLevel.w); half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[2], config.cluster3, mipLevel.w); half3 bf = tc.pN3; #if _TRIPLANARHEIGHTBLEND bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN3, contrasts.x); tc.pN3 = bf; #endif albedo3 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z; } #endif #else albedo0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv0, config.cluster0, mipLevel.x).a; #if _BRANCHSAMPLES UNITY_BRANCH if (weights.y > 0) #endif albedo1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv1, config.cluster1, mipLevel.y).a; #if !_MAX2LAYER #if _BRANCHSAMPLES UNITY_BRANCH if (weights.z > 0) #endif albedo2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv2, config.cluster2, mipLevel.z).a; #endif #if !_MAX3LAYER || !_MAX2LAYER #if _BRANCHSAMPLES UNITY_BRANCH if (weights.w > 0) #endif albedo3 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv3, config.cluster3, mipLevel.w).a; #endif #endif #endif //_DISABLESPLATMAPS #if !_DISABLESPLATMAPS && _DISTANCERESAMPLE && (_DISTANCERESAMPLENOFADE || _DISTANCERESAMPLENOISE) DistanceResampleLOD(albedo0, albedo1, config, tc, levelFx, worldPos, weights, normal); #endif #if (_PERTEXTESSDISPLACE || _PERTEXTESSOFFSET || _PERTEXTESSUPBIAS) && !_DISABLESPLATMAPS SAMPLE_PER_TEX(perTexDispOffsetBias, 6.5, config, half4(1.0, 0.0, 0, 0.0)); #endif float shaping = _TessData2.z; #if _PERTEXTESSSHAPING && !_DISABLESPLATMAPS SAMPLE_PER_TEX(perTexShaping, 14.5, config, half4(0.5, 0.5, 0.5, 0.5)); shaping = perTexShaping0.a * weights.x + perTexShaping1.a * weights.y + perTexShaping2.a * weights.z + perTexShaping3.a * weights.w; #endif #if _NOISEHEIGHT float oldAlb0 = albedo0; float oldAlb1 = albedo1; float oldAlb2 = albedo2; float oldAlb3 = albedo3; ApplyNoiseHeightLOD(albedo0, albedo1, albedo2, albedo3, config.uv, config, vertex.rgb, normal); #endif float4 heightWeights = ComputeWeights(weights, albedo0, albedo1, albedo2, albedo3, shaping); #if _NOISEHEIGHT albedo0 = oldAlb0; albedo1 = oldAlb1; albedo2 = oldAlb2; albedo3 = oldAlb3; #endif #if _PERTEXTESSDISPLACE && !_DISABLESPLATMAPS albedo0 *= perTexDispOffsetBias0.x; albedo1 *= perTexDispOffsetBias1.x; #if !_MAX2LAYER albedo2 *= perTexDispOffsetBias2.x; #endif #if !_MAX3LAYER || !_MAX2LAYER albedo3 *= perTexDispOffsetBias3.x; #endif #endif #if _PERTEXTESSOFFSET && !_DISABLESPLATMAPS albedo0 += perTexDispOffsetBias0.z; albedo1 += perTexDispOffsetBias1.z; albedo2 += perTexDispOffsetBias2.z; albedo3 += perTexDispOffsetBias3.z; #endif #if _MESHOVERLAYSPLATS || _MESHCOMBINED if (_MeshAlphaIndex == config.uv0.z) { albedo0 = 0; } else if (_MeshAlphaIndex == config.uv1.z) { albedo1 = 0; } #if !_MAX2LAYER else if (_MeshAlphaIndex == config.uv2.z) { albedo2 = 0; } #endif #if !_MAX3LAYER || !_MAX2LAYER else if (_MeshAlphaIndex == config.uv3.z) { albedo3 = 0; } #endif #endif #if _DECAL_TESS DoDecalBlendTess(decalOutput, albedo0, albedo1, albedo2, albedo3, mipLevel); #endif #if _TRAXSINGLE || _TRAXARRAY || _TRAXNOTEXTURE || _SNOWFOOTSTEPS ApplyTraxTess(albedo0, albedo1, albedo2, albedo3, config, worldPos, traxBuffer, _TessData1.z, _TessData1.y); #endif half h = albedo0 * heightWeights.x + albedo1 * heightWeights.y + albedo2 * heightWeights.z + albedo3 * heightWeights.w; #if _MESHCOMBINEDHEIGHT || _MESHCOMBINEDPACKEDMAP h = SampleMeshCombinedTess(h, heightWeights, config, _TessData1.z); #endif #if _PUDDLES || _STREAMS || _LAVA #if _STREAMS && _STREAMHEIGHTFILTER { float shf = saturate((worldPos.y - _StreamFades.x) / max(_StreamFades.y - _StreamFades.x, 0.0001)); shf *= 1.0 - saturate((worldPos.y - _StreamFades.z) / max(_StreamFades.w - _StreamFades.z, 0.0001)); levelFx.b *= shf; } #endif #if _LAVA && _LAVAHEIGHTFILTER { float lhf = saturate((worldPos.y - _LavaFades.x) / max(_LavaFades.y - _LavaFades.x, 0.0001)); lhf *= 1.0 - saturate((worldPos.y - _LavaFades.z) / max(_LavaFades.w - _LavaFades.z, 0.0001)); levelFx.a *= lhf; } #endif half maxLevel = max(max(levelFx.g, levelFx.b), levelFx.a); h = max(h, maxLevel); #endif #if _SNOW float snowAmount = DoSnowDisplace(h, texcoord.xy, worldNormal, worldPos, 0, config, weights); #if _SNOWFOOTSTEPS snowAmount *= traxBuffer; #endif #if _WETNESSMASKSNOW snowAmount *= 1-levelFx.x; #endif h = lerp(h + snowAmount * _TessDisplaceSnowMultiplier, max(h, snowAmount * _TessDisplaceSnowMultiplier), pow(saturate(snowAmount - 0.3), 2.0)); //h += snowAmount * _TessDisplaceSnowMultiplier; #endif #if _SNOW && _SNOWFOOTSTEPS h = lerp(h/3.0, h, traxBuffer); // maybe expose this? #endif float dist = distance(_WorldSpaceCameraPos, worldPos); float tessFade = saturate((dist - _TessData2.x) / (_TessData2.y - _TessData2.x)); tessFade *= tessFade; tessFade = 1 - tessFade; half upBias = _TessData2.w; #if _PERTEXTESSUPBIAS && !_DISABLESPLATMAPS upBias = BlendWeights(perTexDispOffsetBias0.y, perTexDispOffsetBias1.y, perTexDispOffsetBias2.y, perTexDispOffsetBias3.y, weights); #endif float3 offset = (lerp(normal, float3(0,1,0), upBias) * (_TessData1.y * h * tessFade)); #if _DISPLACEMENTDAMPENING offset *= (1.0 - SAMPLE_TEXTURE2D_LOD(_DisplacementDampening, sampler_Diffuse, controlUV, 0).g); #endif // fade tessellation near alpha holes. This helps seem stuff with digger, etc. #if defined(_ALPHATEST_ON) && _TESSFADEHOLES { float2 cuv = floor(controlUV * _TerrainHolesTexture_TexelSize.zw + 0.5) * _TerrainHolesTexture_TexelSize.xy; float hole = SAMPLE_TEXTURE2D_LOD(_TerrainHolesTexture, shared_linear_clamp_sampler, cuv, 0).r; hole = saturate((hole - 0.5) * 2); offset *= hole; } #endif #if _ALPHAHOLETEXTURE { float2 cuv2 = floor(controlUV * _AlphaHoleTexture_TexelSize.zw + 0.5) * _AlphaHoleTexture_TexelSize.xy; offset *= SAMPLE_TEXTURE2D_LOD(_AlphaHoleTexture, shared_linear_clamp_sampler, cuv2, 0).r; } #endif return offset; }