void intersect_cone_exp(inout vec3 dp, in vec3 ds, in float dist_factor)
{
	float iz = max(abs(ds.x), abs(ds.y));
	float ht, old_ht, cr;

	int limit = 16;	/// Berserker: protection from infinity loop

	float lod = ComputeLOD(dp.xy, u_texSize);
	vec2 t = TextureLod(u_HeightMap, dp.xy, lod, u_HeightMapSwizzle).rg;
	while (t.r > dp.z && limit>0)
	{
		cr = t.g * t.g;
		dp += ds * (dist_factor + (t.r - dp.z) * cr) / (iz + cr);
		t = TextureLod(u_HeightMap, dp.xy, lod, u_HeightMapSwizzle).rg;
		limit--;
	}
	
	ht = (t.r - dp.z);
	dist_factor /= (iz + cr);
	dp -= ds * dist_factor;

	t.r = TextureLod(u_HeightMap, dp.xy, lod, u_HeightMapSwizzle).r;
	old_ht = t.r - dp.z;

	dp += ds * dist_factor * (1.0 - clamp (ht / (ht - old_ht), 0.0, 1.0));

	t = TextureLod(u_HeightMap, dp.xy, lod, u_HeightMapSwizzle).rg;
	dp += ds * (t.r - dp.z) / (iz / (t.g * t.g) + 1.0);
}
