2017-10-19 106 views
1

我目前正在尝试在glsl(使用SFML)中编写简单的轮廓着色器。如果问题很明显,我对着色器程序设计很陌生,所以请原谅我。 无论如何,着色器对纹理内的边缘检测效果不错,但未能检测到纹理边缘处的边界。工作outlineShader
Picture of the working outlineShader如何检查片段是否位于纹理的边缘

图片轮廓着色器的

图片不能正常工作
Picture of the outline shader not working correctly

这里是我的片段着色器的代码(我只有一个片段着色器)

uniform sampler2D texture; 
uniform float outlineThickness; 
uniform vec2 textureSize; 
uniform vec3 outlineColor; 

void main() 
{ 
    vec2 offx = vec2(outlineThickness/textureSize.x, 0.0); 
    vec2 offy = vec2(0.0, outlineThickness/textureSize.y); 

    float surroundingAlphaSum = texture2D(texture, gl_TexCoord[0].xy + offx).a + 
     texture2D(texture, gl_TexCoord[0].xy - offx).a + 
     texture2D(texture, gl_TexCoord[0].xy + offy).a + 
     texture2D(texture, gl_TexCoord[0].xy - offy).a; 

    // This pixel 
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); 

    // If one of the surrounding pixels is transparrent --> an edge is detected 
    if (4.0 * pixel.a - surroundingAlphaSum > 0.0) 
    pixel = vec4(outlineColor, 1.0); 
    else 
    pixel = vec4(0.0); // transparrent 

    gl_FragColor = pixel * gl_Color; 
} 

所以基本上我正在寻找的是一种方法来确定是否邻近像素仍属于纹理或不。

因为gl_TexCoord[0].xy似乎在shadermodel #version 120之后被删除,所以备选将是非常值得赞赏的。

感谢您的帮助,

阿德里安

回答

0

有几种方法来detect edges。不幸的是,我刚刚在Matlab中与他们合作,但也许链接可以帮助你实现一些功能。

根据我以往的经验,你必须用它包含图像,然后矩阵工作,创造一个你计算每个像素的额外的矩阵,如果它是一个边缘与否,与0或1

0

你试过采样8个纹素?看起来你的内核在某些情况下是不完美的。

float surroundingAlphaSum = texture2D(texture, gl_TexCoord[0].xy + offx).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx).a + 
    texture2D(texture, gl_TexCoord[0].xy + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offy).a + 
    texture2D(texture, gl_TexCoord[0].xy + offx + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy + offx - offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx + offy).a + 
    texture2D(texture, gl_TexCoord[0].xy - offx - offy).a; 

// ... 

if (8.0 * pixel.a - surroundingAlphaSum > 0.0) 

// ... 
+0

是的,那是我的第一次尝试。我通过首先在较大的(transparrent)渲染纹理上绘制,然后将该着色器应用于renderTexture,找到了解决方法。它的工作原理是边缘不再位于纹理的边缘,但坦克性能相当高。感谢您回复^^ –