GLSL 2D圆角

时间:2016-08-28 18:05:35

标签: opengl glsl rounded-corners

我想在我的游戏画面中添加一些黑色轮廓,使其看起来像是圆角。 这是我想要实现的效果: rounded corners

我认为这种效果可能很容易使用着色器创建,而不是在所有内容上绘制一个巨大的位图。

有人可以帮我解决此效果的GLSL着色器代码吗?我对着色器有0次经验,但在互联网上找不到这样的东西。

2 个答案:

答案 0 :(得分:7)

我偶然发现了一个很好的解决方案。不完全是你所要求的,但事实上它看起来更好。

library(deSolve)

Dyn <- function(t, var,par) {

  with(as.list(c(par, var)), {

    for(s in 1:2){ 

      #Derivatives
      dX[s] <- mu*N[s] - sigma*X[s] - (c[s]*beta*(InD[s] +ID[s]+ IdT[s])/N[s])*X[s] - mu*X[s]

      dXint[s] <- sigma*X[s] - (1-omega)*(c[s]*beta*(InD[s] +ID[s]+ IdT[s])/N[s])*Xint[s] - mu*Xprep[s] 

      dInD[s] <- (c[s]*beta*(InD[s] +ID[s]+ IdT[s])/N[s])*X[s] - psi*InD[s]- mu*InD[s]

      dID[s] <- (1-omega)*(c[s]*beta*(InD[s] +ID[s]+ IdT[s]) /N[s])*Xint[s]+ psi*InD[s]- mu*ID[s]

      N[s] <- X[s]+Xint[s]+InD[s]+ID[s]

      diffs <- c(dX[s], dXint[s], dInD[s], dID[s], N[s])}

    return(list(diffs))

  })}

#Defining parameter and initial values 

par <- c(mu=0.033, sigma=0.29, beta=0.40, c=c(2, 30), Ctot=1773600, N=c(332550, 36950), psi=0.022, omega=0.44)

init <- c(X=c(332550,36950), Xint=c(0,0), InD=c(1,1), ID=c(0,0))

t <- seq(0, 30, by=0.1) 

#Numerical solution#

Hom.sol <- lsoda(init, t, Dyn,par)

它给出了以下结果:

enter image description here

如果您不喜欢这些细线,可以通过升级图像来移除它们。可以通过添加以下行来完成:

// 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);

enter image description here

虽然这种效果看起来很好,但是添加一个微弱的阴影可能更聪明 使用相同的等式很容易实现:// 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)到中心的0.0 您可以使用一些简单的数学方法来制作一个靠近窗口边缘变得更厚的阴影 Here is an example of how it may look.
(来自Duality的截图,我的Ludum Dare 35条目。)

答案 1 :(得分:3)

感谢@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的resize事件中按如下方式设置制服:

shader.begin();
shader.setUniformf("u_resolution", viewport.getScreenWidth(), viewport.getScreenHeight());
shader.setUniformf("u_screenOffset", viewport.getScreenX(), viewport.getScreenY());
shader.end();

这将确保着色器适用于视口(仅使用FitViewport测试)。