Com relação a este tópico, implementei com êxito o filtro Sobel Edge Detection no GLSL. Aqui está o código do shader de fragmento do filtro:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D screenTexture;
mat3 sx = mat3(
1.0, 2.0, 1.0,
0.0, 0.0, 0.0,
-1.0, -2.0, -1.0
);
mat3 sy = mat3(
1.0, 0.0, -1.0,
2.0, 0.0, -2.0,
1.0, 0.0, -1.0
);
void main()
{
vec3 diffuse = texture(screenTexture, TexCoords.st).rgb;
mat3 I;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
vec3 sample = texelFetch(screenTexture, ivec2(gl_FragCoord) + ivec2(i-1,j-1), 0 ).rgb;
I[i][j] = length(sample);
}
}
float gx = dot(sx[0], I[0]) + dot(sx[1], I[1]) + dot(sx[2], I[2]);
float gy = dot(sy[0], I[0]) + dot(sy[1], I[1]) + dot(sy[2], I[2]);
float g = sqrt(pow(gx, 2.0)+pow(gy, 2.0));
color = vec4(diffuse - vec3(g), 1.0);
}
E aqui está o resultado de um cubo com detecção de borda Sobel:
Se você ampliar a imagem, verá que há muito "ruído" produzido por Sobel: existem faixas horizontais cinzentas em toda a cena devido ao gradiente de azul / branco. Além disso, os cones de luz produzem um padrão indesejado no cubo. As bordas pretas à esquerda do cubo também parecem desaparecer devido ao cone de luz na metade esquerda do cubo.
Então, li este artigo que afirmava que a imagem deveria ser em escala de cinza primeiro e usar um filtro de desfoque gaussiano para tornar as bordas mais aparentes. Na parte inferior do artigo, há também o filtro de detecção de borda inteligente que parece produzir melhores resultados.
Agora eu tenho duas perguntas:
As etapas a seguir estão corretas para produzir os melhores resultados possíveis de detecção de borda:
- Escala de cinza
- Gaussian Blur
- Detecção de borda de Sobel / Canny
Se sim, como mesclar a imagem original com a imagem processada? Quero dizer, depois de processar as etapas mencionadas acima, recebo uma imagem totalmente preta com bordas brancas ou vice-versa. Como eu colocaria as bordas na minha imagem / textura original?
Obrigado pela ajuda!