详解OpenGL Shader抗锯齿的实现

 更新时间:2022年02月11日 16:04:27   作者:JulyYu  
普通绘制圆形形状时可以看到图形边缘会有明显锯齿现象并不像真实圆形形状一样圆润边缘平滑。本文将介绍如何通过自制函数实现抗锯齿,需要的可以参考一下

绘制圆形锯齿问题

普通绘制圆形形状时可以看到图形边缘会有明显锯齿现象并不像真实圆形形状一样圆润边缘平滑。在glsl中这种情况是常见情况,这里是可以借助glsl内置函数来消除锯齿现象。

vec3 sdfCircle(vec2 uv,float r,vec3 value){
    float d = length(uv) - r;
    return d > 0. ? vec3(0.3294, 0.3294, 0.9333) : value; // 大于0超出画圆范围,小于0在画圆范围内
}
void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5>
    uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5>
    vec3 circle = sdfCircle(uv,0.4,vec3(1.));
    circle = mix(circle,sdfCircle(uv,0.3,vec3(1.)),0.5);
    circle = mix(circle,sdfCircle(uv,0.2,vec3(1.)),0.7);
    gl_FragColor = vec4(circle,.9);
}

smoothstep函数介绍

smoothstep(a, b, x)函数结果范围:

返回值条件
0x<a<b 或 x>a>b
1x<b<a 或 x>b>a
某个值根据x在[a,b]或[b,a]区间范围内,返回一个在[0,1]之间的值

内置函数smoothstep就能实现绘制圆形图形的抗锯齿效果。可能之前有使用过内置函数step同样都是步进式功能函数,不同于step函数可以理解为if-elsesmoothstep函数是平滑过渡的。

抗锯齿实现

使用smoothstep实现抗锯齿功能需要修改一下原先的画圆公式。原来只需要使用到length(uv) - r来判断是否选择绘制圆的颜色,而现在需要修改成通过smoothstep(m-0.002,m+0.002,length(uv) - 0.2)计算值作为mix函数混合系数值来实现平滑过渡到画圆色值,这样就能实现抗锯齿了。

    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5>
    uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5>
    float m = 0.2;
    m = smoothstep(m-0.002,m+0.002,length(uv) - 0.2);
    vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m);
    gl_FragColor = vec4(pixel,1.0);

如果把脚本其中m-0.002,m+0.0020.002范围进行修改。例如修改成0.02,运行结果可以发现圆形变模糊了。这就是区间过大导致平滑区间渐变范围在肉眼可见范围了,因此设置一个适当过渡区间才能实现较好的抗锯齿效果。

扩展

清楚实现抗锯齿原理之后,可以根据需要自行实现一个平滑过渡函数来实现抗锯齿功能。类似像以下两个自制平滑过渡函数最终实现效果几乎看不出太大区别。

自制smoothstep函数抗锯齿

float smootherstep(float edge0, float edge1, float x) {
    float t = (x - edge0)/(edge1 - edge0);
    float t1 = t*t*t*(t*(t*6. - 15.) + 10.);
    return clamp(t1, 0.0, 1.0);
}
void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5>
    uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5>
    float m = 0.2;
    m = smootherstep(m-0.002,m+0.002,length(uv) - 0.2);
    vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m);
    gl_FragColor = vec4(pixel,1.0);
}

自制linearstep函数抗锯齿

float linearstep(float edge0, float edge1, float x) {
    float t = (x - edge0)/(edge1 - edge0);
    return clamp(t, 0.0, 1.0);
}
void main(){
   vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5>
    uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5>
    float m = 0.2;
    m = linearstep(m-0.002,m+0.002,length(uv) - 0.2);
    vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m);
    gl_FragColor = vec4(pixel,1.0);
}

smoothstep

linearstep

以上就是详解OpenGL Shader抗锯齿的实现的详细内容,更多关于OpenGL Shader抗锯齿的资料请关注脚本之家其它相关文章!

相关文章

  • Android DataBinding单向数据绑定深入探究

    Android DataBinding单向数据绑定深入探究

    看了谷歌官方文章确实写的太简略了,甚至看完之后有很多地方还不知道怎么回事儿或者怎么用,那么接下来我将通过文章全面介绍一下DataBinding单向数据绑定
    2022-11-11
  • Android自定义ViewGroup多行多列效果

    Android自定义ViewGroup多行多列效果

    这篇文章主要为大家详细介绍了Android自定义ViewGroup多行多列效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Android实现一个简单的单词本

    Android实现一个简单的单词本

    大家好,本篇文章主要讲的是Android实现一个简单的单词本,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • Android实现读取SD卡下所有TXT文件名并用listView显示出来的方法

    Android实现读取SD卡下所有TXT文件名并用listView显示出来的方法

    这篇文章主要介绍了Android实现读取SD卡下所有TXT文件名并用listView显示出来的方法,涉及Android针对SD卡的读取及文件遍历等相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • Android中打电话的数据流程分析

    Android中打电话的数据流程分析

    所有流程的起点是从拨号后按下拨号键开始,接下来将对打电话的数据流程进行源码分析,感兴趣的朋友可以了解下
    2013-01-01
  • Android  Spinner列表选择框的应用

    Android Spinner列表选择框的应用

    这篇文章主要介绍了Android Spinner列表选择框的应用的相关资料,这里对spinner的属性和常用事件和数据绑定都做了介绍,需要朋友可以参考下
    2017-07-07
  • Android UI效果之绘图篇(一)

    Android UI效果之绘图篇(一)

    这篇文章主要介绍了Android UI效果之绘图篇,针对Android开发中的UI效果设计模块进行讲解,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • android使用surfaceview+MediaPlayer播放视频

    android使用surfaceview+MediaPlayer播放视频

    这篇文章主要为大家详细介绍了android使用surfaceview+MediaPlayer播放视频,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Android实现欢迎滑动页面

    Android实现欢迎滑动页面

    这篇文章主要为大家详细介绍了Android实现欢迎滑动页面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Android 自定义缩短Toast显示时间的实例代码

    Android 自定义缩短Toast显示时间的实例代码

    这篇文章主要介绍了Android 自定义缩短Toast显示时间,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01

最新评论