GLSL 2D 圆角
GLSL 2D Rounded corners
我想在我的游戏屏幕上添加一些黑色轮廓,使它看起来像是圆角。
这是我想要达到的效果:
我认为使用着色器创建这种效果可能很容易,而不是在所有内容之上绘制一个巨大的位图。
有人可以帮我处理这个效果的 GLSL 着色器代码吗?我有 0 个着色器经验,无法在互联网上找到类似的东西。
我无意中找到了一个很好的解决方案。不完全符合您的要求,但实际上它看起来更好。
// RESOLUTION is a vec2 with your window size in pixels.
vec2 pos = fragCoord.xy / RESOLUTION;
// Adjust .2 (first pow() argument) below to change frame thickness.
if (pos.x * pos.y * (1.-pos.x) * (1.-pos.y) < pow(.2,4.))
fragColor = vec4(0,0,0,1);
结果如下:
如果你不喜欢那些细线,你可以通过放大图像来删除它们。可以通过添加此行来完成:
// The .985 is 1/scale_factor. You can try to change it and see how it works.
// It needs to be adjusted if you change frame thickness.
pos = (pos - .5) * .985 + .5;
虽然这个效果看起来不错,但只添加一个微弱的阴影可能更聪明。
使用相同的等式很容易实现:pos.x * pos.y * (1.-pos.x) * (1.-pos.y)
它的值范围从 window 边缘的 0.0
到中心的 0.5^4
。
您可以使用一些简单的数学运算来使阴影在靠近 window 边缘时变得更厚。
Here is an example of how it may look.
(来自 Duality 的屏幕截图,我的 Ludum Dare 35 条目。)
感谢@HolyBlackCat,我的着色器现在可以工作了。我改进了性能并使其看起来更平滑。
varying vec4 v_color;
varying vec2 v_texCoord0;
uniform vec2 u_resolution;
uniform vec2 u_screenOffset;
uniform sampler2D u_sampler2D;
const float max = pow(0.2, 4);
void main()
{
vec2 pos = (gl_FragCoord.xy - u_screenOffset) / u_resolution;
float vignette = pos.x * pos.y * (1.-pos.x) * (1.-pos.y);
vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color;
color.rgb = color.rgb * smoothstep(0, max, vignette);
gl_FragColor = color;
}
在libGDX的调整大小事件中设置制服如下:
shader.begin();
shader.setUniformf("u_resolution", viewport.getScreenWidth(), viewport.getScreenHeight());
shader.setUniformf("u_screenOffset", viewport.getScreenX(), viewport.getScreenY());
shader.end();
这将确保着色器也适用于视口(仅使用 FitViewport 测试过)。
我想在我的游戏屏幕上添加一些黑色轮廓,使它看起来像是圆角。
这是我想要达到的效果:
我认为使用着色器创建这种效果可能很容易,而不是在所有内容之上绘制一个巨大的位图。
有人可以帮我处理这个效果的 GLSL 着色器代码吗?我有 0 个着色器经验,无法在互联网上找到类似的东西。
我无意中找到了一个很好的解决方案。不完全符合您的要求,但实际上它看起来更好。
// RESOLUTION is a vec2 with your window size in pixels.
vec2 pos = fragCoord.xy / RESOLUTION;
// Adjust .2 (first pow() argument) below to change frame thickness.
if (pos.x * pos.y * (1.-pos.x) * (1.-pos.y) < pow(.2,4.))
fragColor = vec4(0,0,0,1);
结果如下:
如果你不喜欢那些细线,你可以通过放大图像来删除它们。可以通过添加此行来完成:
// The .985 is 1/scale_factor. You can try to change it and see how it works.
// It needs to be adjusted if you change frame thickness.
pos = (pos - .5) * .985 + .5;
虽然这个效果看起来不错,但只添加一个微弱的阴影可能更聪明。
使用相同的等式很容易实现:pos.x * pos.y * (1.-pos.x) * (1.-pos.y)
它的值范围从 window 边缘的 0.0
到中心的 0.5^4
。
您可以使用一些简单的数学运算来使阴影在靠近 window 边缘时变得更厚。
Here is an example of how it may look.
(来自 Duality 的屏幕截图,我的 Ludum Dare 35 条目。)
感谢@HolyBlackCat,我的着色器现在可以工作了。我改进了性能并使其看起来更平滑。
varying vec4 v_color;
varying vec2 v_texCoord0;
uniform vec2 u_resolution;
uniform vec2 u_screenOffset;
uniform sampler2D u_sampler2D;
const float max = pow(0.2, 4);
void main()
{
vec2 pos = (gl_FragCoord.xy - u_screenOffset) / u_resolution;
float vignette = pos.x * pos.y * (1.-pos.x) * (1.-pos.y);
vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color;
color.rgb = color.rgb * smoothstep(0, max, vignette);
gl_FragColor = color;
}
在libGDX的调整大小事件中设置制服如下:
shader.begin();
shader.setUniformf("u_resolution", viewport.getScreenWidth(), viewport.getScreenHeight());
shader.setUniformf("u_screenOffset", viewport.getScreenX(), viewport.getScreenY());
shader.end();
这将确保着色器也适用于视口(仅使用 FitViewport 测试过)。