Opengl es 用于勾勒二维图像轮廓的OpenGL ES着色器

Opengl es 用于勾勒二维图像轮廓的OpenGL ES着色器,opengl-es,shader,Opengl Es,Shader,我正在使用OpenGL 2.0开发一个2D iOS游戏,我想知道是否有可能编写一个着色器,用光晕勾勒出图像的轮廓。所有图像都是2D精灵。我看到的用于勾勒轮廓的着色器示例是针对3D对象的,因此我不确定2D图像是否可行。您是否接受边缘检测过滤器(如Sobel),生成如中所示的图像,然后在其结果上加上高斯模糊,以软化边缘并使其更具光泽,然后将图像合成到场景中 在实践中,您可能只需要重用您所看到的3d大纲着色器-尽管理论上您可以检查深度量(在ES中进行了一些扩展工作),但我所看到的每一个着色器都只是渲染

我正在使用OpenGL 2.0开发一个2D iOS游戏,我想知道是否有可能编写一个着色器,用光晕勾勒出图像的轮廓。所有图像都是2D精灵。我看到的用于勾勒轮廓的着色器示例是针对3D对象的,因此我不确定2D图像是否可行。

您是否接受边缘检测过滤器(如Sobel),生成如中所示的图像,然后在其结果上加上高斯模糊,以软化边缘并使其更具光泽,然后将图像合成到场景中

在实践中,您可能只需要重用您所看到的3d大纲着色器-尽管理论上您可以检查深度量(在ES中进行了一些扩展工作),但我所看到的每一个着色器都只是渲染图像上的2d效果

编辑:进一步考虑,拉普拉斯算子可能比Sobel算子更容易应用,因为它可以作为一个简单的卷积着色器(如中所述)。虽然为了在移动设备上安全起见,您可能希望最多使用3x3内核,并为每个效果编写不同的着色器,而不是使用数据。例如,一个粗略的高斯模糊,写在长度上:

void main()
{
    mediump vec4 total = vec4(0.0);
    mediump vec4 grabPixel;

    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 1.0 / height));

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, -1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, 1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel = texture2D(tex2D, texCoordVarying);
    total += grabPixel * 4.0;

    total *= 1.0 / 16.0;

    gl_FragColor = total;
}
拉普拉斯边缘检测结果看起来相似,但常数不同


作为一种优化,您应该尽可能在顶点着色器中计算相对采样点,而不是在片段着色器中,因为这样做可以避免依赖纹理读取

所以你想要添加的光晕就像一个阴影?更多的是围绕图像的一个笔划,它会有柔软的边缘。也许我没有看到正确的3D效果,但我看到的效果似乎在某种程度上对光源起作用,我没有给出2D效果。我对着色器非常陌生,所以我可能忽略了这里显而易见的一点。许多后置无线单元着色器通过将一条边定义为前向边和后向边之间的连接,使用摄影机位置来检测边。很明显,你不能使用其中的一个。但是像索贝尔和拉普拉斯这样的方法在2d图像中寻找颜色的不连续性来发现边缘,所以是完全合适的。如果你还没有读过卷积滤波器,那么研究拉普拉斯和高斯模糊可能是明智的。我为后者添加了一些匆忙组装的示例代码。