如何使用GLSL实现边框模糊效果?

huangapple go评论61阅读模式
英文:

How can I give a border blur effect with GLSL?

问题

为了让它具有真实光束项目的感觉,我使用了一个使用RawShaderMaterial创建的着色器,显示从边缘传入的模糊效果。

然而,我在每个角落都看到了对角线,而且我很难让它正常工作。

有谁可以帮助我修改我的代码,使其正确运行?或者如果您有其他自然实现模糊着色器的想法,请告诉我。

英文:

To give it the feel of a real beam project, I created a shader using a RawShaderMaterial that shows the blur coming in from the edges.

However, I'm getting diagonal lines in each corner, and I'm having trouble getting it to work.

Can anyone help me modify my code to make it work correctly? Or if you have any other ideas to implement the blur shader naturally, please let me know.

答案1

得分: 0

不要翻译的代码部分:

  float edgeMin = edge;
  float edgeMax = 1.0 - edge;

  gl_FragColor = texture2D( map, vUv );
  // dx => lilnear distance parallel to x from vUv to rectangle
  // (0.5, 0.5) is the center of the rectangle in uv
  // the abs and max work together to make any vUv inside the 
  // rectangle return 0
  float dx = max(abs(vUv.x - 0.5) - (0.5 - edge), 0.);
  // similarly for dy, along the parallel to y
  float dy = max(abs(vUv.y - 0.5) - (0.5 - edge), 0.);
  // d is the result of a Euclidean distance; this rounds the corners
  float d = sqrt(dx * dx + dy * dy);
  // alpha should be opacity at the edge of the rectangle, and also 
  // inside of it (all where d == 0), and 0. at the edge of the plane
  // (where d == edge).  So we do an inverse lerp.
  gl_FragColor.a = opacity - opacity * d / edge;
}

翻译部分:

考虑到vUv在_x_和_y_两个维度上的范围为[0 .. 1],地图未淡化的区域是在这两个维度上都在[edge .. 1 - 2 * edge]之间的一个轴对齐矩形。我们可以省略所有条件,并使用从vUv到该矩形的距离。

在上述代码中,我们首先定义了edgeMin和edgeMax,它们分别表示edge的最小值和最大值。

接着,我们使用texture2D函数获取vUv位置处的纹理颜色。

然后,我们计算了dx和dy,它们分别代表vUv到矩形边缘的平行x和y距离。在这里,我们使用了abs和max函数,以确保任何vUv位于矩形内部的值都为0。

接下来,我们通过计算dx和dy的欧几里得距离得到了d,这将使矩形的边角变得圆滑。

最后,我们计算了alpha,这是在矩形边缘和内部(当d == 0)的不透明度,并在平面边缘(当d == edge)为0。因此,我们执行了逆lerp操作以计算gl_FragColor.a的值。

英文:

Bearing in mind that vUv ranges [0 .. 1] in both x and y, the area where the map is not faded, is an axis-aligned rectangle over [edge .. 1 - 2 * edge] in both dimensions. We can drop all the conditionals and use the distance from vUv to that rectangle.

    void main(){
      float edgeMin = edge;
      float edgeMax = 1.0 - edge;

      gl_FragColor = texture2D( map, vUv );
      // dx => lilnear distance parallel to x from vUv to rectangle
      // (0.5, 0.5) is the center of the rectangle in uv
      // the abs and max work together to make any vUv inside the 
      // rectangle return 0
      float dx = max(abs(vUv.x - 0.5) - (0.5 - edge), 0.);
      // similarly for dy, along the parallel to y
      float dy = max(abs(vUv.y - 0.5) - (0.5 - edge), 0.);
      // d is the result of a Euclidean distance; this rounds the corners
      float d = sqrt(dx * dx + dy * dy);
      // alpha should be opacity at the edge of the rectangle, and also 
      // inside of it (all where d == 0), and 0. at the edge of the plane
      // (where d == edge).  So we do an inverse lerp.
      gl_FragColor.a = opacity - opacity * d / edge;

    }

huangapple
  • 本文由 发表于 2023年2月10日 15:41:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75408176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定