我正在使用OpenGL 2.0开发一款2D iOS游戏,我想知道是否可以编写一个可以勾勒出发光图像的着色器.所有图像都是2D精灵.我看到的用于概述的着色器示例是针对3D对象的,因此我不确定2D图像是否可能.
你会接受边缘检测滤镜(例如Sobel),产生类似维基百科文章中所示的图像,然后对其结果进行高斯模糊以软化边缘并使其更多地发光,然后合成该图像到你的场景?
在实践中,您可能只是重复使用您已经看过的3D轮廓着色器 - 尽管您理论上可以检查深度量(在ES中有一些扩展的努力),但我所见过的每一个都只是对渲染图像的二维效果.
编辑:关于进一步审议,拉普拉斯可能会更容易一些比索贝尔申请,因为它可以作为一个简单的卷积着色器来完成(如地方描述是这样).虽然为了在移动设备上安全,你可能想要最多坚持使用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;
}
Run Code Online (Sandbox Code Playgroud)
并且拉普拉斯边缘检测最终看起来相似但具有不同的常数.
作为优化,您应该在顶点着色器中而不是在片段着色器中计算出相对采样点,并尽可能考虑到变化的限制,因为这样做会避免依赖纹理读取.