【发布时间】:2012-01-25 07:45:41
【问题描述】:
我正在开发一个使用 OpenGL 2.0 的 2D iOS 游戏,我想知道是否可以编写一个着色器来为图像勾勒出发光的轮廓。所有图像都是二维精灵。我看到的用于勾画轮廓的着色器示例是针对 3D 对象的,所以我不确定是否可以用于 2D 图像。
【问题讨论】:
-
所以你想要添加的光晕就像一个投影?
-
图像周围有更多的笔触,边缘柔和。
我正在开发一个使用 OpenGL 2.0 的 2D iOS 游戏,我想知道是否可以编写一个着色器来为图像勾勒出发光的轮廓。所有图像都是二维精灵。我看到的用于勾画轮廓的着色器示例是针对 3D 对象的,所以我不确定是否可以用于 2D 图像。
【问题讨论】:
您是否会接受边缘检测过滤器(例如 Sobel),生成像 the Wikipedia article 中所示的图像,然后对其结果进行高斯模糊以柔化边缘并使其更加发光,然后将该图像合成到您的场景中?
在实践中,您可能只重用您见过的 3d 轮廓着色器——尽管理论上您可以检查深度量(在 ES 中进行了一些扩展),但我见过的每一个都只是对渲染图像。
编辑:进一步考虑,Laplacian 可能比 Sobel 更容易应用,因为它可以作为简单的卷积着色器完成(如在地方 like this 中所述)。尽管为了在移动设备上安全起见,您可能最多希望坚持使用 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;
}
拉普拉斯边缘检测最终看起来相似,但常数不同。
作为一项优化,您应该尽可能在顶点着色器中而不是在片段着色器中计算出相对采样点,因为变化的限制,因为这样做可以避免依赖纹理读取。
【讨论】: