Comece encontrando todos os grupos de objetos, onde um grupo de objetos é uma coleção de objetos que se sobrepõem. A detecção de colisão padrão deve fazer o trabalho. Atribua a cada grupo uma cor única. Qualquer cor serviria.
Renderize todos os seus objetos como cores sólidas, usando a cor do grupo, em uma textura.
Crie uma nova textura de contorno com as mesmas dimensões que o destino de renderização. Examine cada texel do destino de renderização e determine se é uma cor diferente de qualquer texels ao redor. Se for, altere o texel correspondente na textura do contorno para a cor da linha desejada.
Por fim, pegue essa textura de contorno e renderize-a na parte superior da imagem que deseja desenhar na tela (é claro que você pode fazer isso ao mesmo tempo que a detecção de borda em um shader de fragmento e evitar criar a textura de borda no primeiro Lugar, colocar).
Se você executar esta etapa no processador usando um loop for para percorrer os texels do destino de renderização, isso será bem lento, mas provavelmente bom o suficiente para testar e até mesmo usar em alguns casos. Para usar isso em tempo real, seria melhor lidar com isso em um sombreador.
Um shader de fragmento para fazer essa detecção de borda pode se parecer com isso;
precision mediump float;
uniform sampler2D s_texture;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = vec4(0.0);
vec4 baseColor = texture2D(s_texture, v_texCoord);
gl_FragColor += baseColor - texture2D(s_texture, top);
gl_FragColor += baseColor - texture2D(s_texture, topRight);
gl_FragColor += baseColor - texture2D(s_texture, right);
gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
gl_FragColor += baseColor - texture2D(s_texture, bottom);
gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
gl_FragColor += baseColor - texture2D(s_texture, left);
gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}
Onde o segundo valor na consulta texture2D é uma coordenada 2D em relação a v_texCoord. Você aplicaria isso renderizando o primeiro destino de renderização como a textura em um quad de tela cheia. É semelhante a como você aplicaria efeitos de desfoque em tela cheia, como um desfoque guassiano.
O motivo para usar o primeiro destino de renderização com cores sólidas é simplesmente garantir que não haja arestas percebidas entre os diferentes objetos que se sobrepõem. Se você simplesmente executasse a detecção de borda na imagem da tela, provavelmente descobriria que ela também detecta bordas nas sobreposições (assumindo que os objetos tenham cores / texturas / iluminação diferentes).