I implemented double paraboloid shadows for point lights. The goal was to reduce the number of shadow passes. GLES3.0 is also a goal, so there is no multi-level rendering. Shadows work, and in fact the quality is not bad. There is one problem. I store both hemisphere maps in the same atlas during a shadow passage. During the passage of lighting, I take a sample from this atlas, from the corresponding part based on the direction (forward or backward). When the shadow crosses both cards there is a white seam in the middle. I tried to change the FBO texture filter mode, also changed the wrapping mode, but nothing helps. Here is a screenshot:

and this is a double shadow mapping: 
- , , . .
GLSL :
float Shadow(vec3 viewPos,vec3 lightViewPos,vec3 viewNormal,float bias)
{
vec3 vPosDP = vec3(u_lightViewMatrix * v_worldPosition);
float fLength = length(vPosDP);
vPosDP /= fLength;
lightViewPos = (u_viewMatrix * vec4(lightViewPos,1.0)).xyz;
vec3 L = normalize(lightViewPos - viewPos);
float NdotL = saturate(dot(L, viewNormal));
bias = max(0.01 *(1.0 - NdotL), bias);
float fDPDepth;
float fSceneDepth;
if(vPosDP.z >= 0.0)//one side
{
vec2 vTexFront;
vTexFront.x = ((vPosDP.x / (1.0 + vPosDP.z)) * 0.25 + 0.25 );
vTexFront.y = ((vPosDP.y / (1.0 + vPosDP.z)) * 0.5 + 0.5 );
fSceneDepth = (fLength - u_nearFarPlanes.x) / (u_nearFarPlanes.y - u_nearFarPlanes.x);
fDPDepth = texture(u_shadowMap, vec3(vTexFront,fSceneDepth - bias));
}
else //another side
{
vec2 vTexBack;
vTexBack.x = ((vPosDP.x / (1.0 - vPosDP.z)) * 0.25 + 0.75);
vTexBack.y = ((vPosDP.y / (1.0 - vPosDP.z)) * 0.5 + 0.5);
fSceneDepth = (fLength - u_nearFarPlanes.x) / (u_nearFarPlanes.y - u_nearFarPlanes.x);
fDPDepth = texture(u_shadowMap, vec3(vTexBack,fSceneDepth - bias));
}
return fDPDepth;
}
, . ?