vec2 uvNear, uvFar;
nearAndFarTexCoords(uvNear, uvFar);
float textureDistanceFactor = textureDistanceBlendFactor();
// Get grass texture color
vec4 grassNear = texture(grassTexture, uvNear);
vec4 grassFar = texture(grassTexture, texCoords);
vec4 grassColor = mix(grassNear, grassFar, textureDistanceFactor);
// Get rock texture color
vec4 rockNear = texture(rockTexture, uvNear);
vec4 rockFar = texture(rockTexture, uvFar);
vec4 rockColor = mix(rockNear, rockFar, textureDistanceFactor);
// Blend rock and grass texture based upon the worldNormal vector
vec4 grassRockColor = mix(rockColor, grassColor, smoothstep(0.75, 0.95, clamp(worldNormal.y, 0.0, 1.0)));
// Now blend with snow based upon world height
vec4 snowNear = texture(snowTexture, uvNear);
vec4 snowFar = texture(snowTexture, 5.0 * uvFar);
vec4 snowColor = mix(snowNear, snowFar, textureDistanceFactor);
vec4 diffuseColor = mix(grassRockColor, snowColor, smoothstep(10.0, 15.0, worldPosition.y));
// Calculate the lighting model, keeping the specular component separate
vec3 ambientAndDiff, spec;
phongModel(ambientAndDiff, spec);
vec4 color = vec4(ambientAndDiff, 1.0) * diffuseColor + vec4(spec, 1.0);