void intersect_cone_exp2(inout vec3 dp0, inout vec3 dp1, sampler2D Tex0, sampler2D Tex1, in vec3 ds, in float dist_factor, in float swizzle0, in float swizzle1)
{
	int limit;	/// Berserker: protection from infinity loop

	float iz = max(abs(ds.x), abs(ds.y));
	float ht, old_ht, cr;

// stage 0:
	limit = 16;
	float lod0 = ComputeLOD(dp0.xy, u_texSize0);
	vec2 t = TextureLod(Tex0, dp0.xy, lod0, swizzle0).rg;
	while (t.r > dp0.z && limit>0)
	{
		cr = t.g * t.g;
		dp0 += ds * (dist_factor + (t.r - dp0.z) * cr) / (iz + cr);
		t = TextureLod(Tex0, dp0.xy, lod0, swizzle0).rg;
		limit--;
	}
	
	ht = (t.r - dp0.z);
	dist_factor /= (iz + cr);
	dp0 -= ds * dist_factor;

	t.r = TextureLod(Tex0, dp0.xy, lod0, swizzle0).r;
	old_ht = t.r - dp0.z;

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

	t = TextureLod(Tex0, dp0.xy, lod0, swizzle0).rg;
	dp0 += ds * (t.r - dp0.z) / (iz / (t.g * t.g) + 1.0);

// stage 1:
	limit = 16;
	float lod1 = ComputeLOD(dp1.xy, u_texSize1);
	t = TextureLod(Tex1, dp1.xy, lod1, swizzle1).rg;
	while (t.r > dp1.z && limit>0)
	{
		cr = t.g * t.g;
		dp1 += ds * (dist_factor + (t.r - dp1.z) * cr) / (iz + cr);
		t = TextureLod(Tex1, dp1.xy, lod1, swizzle1).rg;
		limit--;
	}
	
	ht = (t.r - dp1.z);
	dist_factor /= (iz + cr);
	dp1 -= ds * dist_factor;

	t.r = TextureLod(Tex1, dp1.xy, lod1, swizzle1).r;
	old_ht = t.r - dp1.z;

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

	t = TextureLod(Tex1, dp1.xy, lod1, swizzle1).rg;
	dp1 += ds * (t.r - dp1.z) / (iz / (t.g * t.g) + 1.0);
}
