详解OpenGL Shader抗锯齿的实现
作者:JulyYu 发布时间:2021-09-24 21:54:07
标签:OpenGL,Shader,抗锯齿
绘制圆形锯齿问题
普通绘制圆形形状时可以看到图形边缘会有明显锯齿现象并不像真实圆形形状一样圆润边缘平滑。在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)
函数结果范围:
返回值 | 条件 |
---|---|
0 | x<a<b 或 x>a>b |
1 | x<b<a 或 x>b>a |
某个值 | 根据x在[a,b]或[b,a]区间范围内,返回一个在[0,1]之间的值 |
内置函数smoothstep
就能实现绘制圆形图形的抗锯齿效果。可能之前有使用过内置函数step
同样都是步进式
功能函数,不同于step
函数可以理解为if-else
而smoothstep
函数是平滑过渡的。
抗锯齿实现
使用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.002
把0.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
来源:https://juejin.cn/post/7060050476238110750


猜你喜欢
- 1.新建控制台应用程序2.新建类 EncryptHelper.cspublic static class EncryptHelper{ &n
- 一、Widget设计步骤需要修改三个XML,一个class:1.第一个xml是布局XML文件(如:main.xml),是这个widget的。
- 在使用面向对象的语言进行项目开发的过程中,较多的会使用到“继承”的特性,但是并非所有的场景都适合使用“
- 1安装eclipse插件步骤,点击help,选择Eclipse Marketplace2.输入Scala,点击go3.选择搜索到的Scala
- Android 自定义 Toast 显示时间实现代码:package com.wm.realname.util;import android
- 根据狂神的视频做的,然后自己优化了一些bug,比如新生成食物的时候不会生成在蛇的身体上,再新增长身体的时候不会在左上角出现一个绿色的方块以及
- 本文调用android的媒体播放器实现一些音乐播放操作项目布局:<LinearLayout xmlns:android="h
- 1.选择一个WebService接口作测试假设 WebService url 为 http://ws.webxml.com.cn/WebSe
- 题目描述:给定一 m*n 的矩阵,请按照逆时针螺旋顺序,返回矩阵中所有元素。示例:思路:这是一道典型的模拟问题:我们可以分析一下,遍历前进轨
- 效果图如下:类注释:方法注释:idea不会默认帮我们设置,所以需要手动设置。1:IDEA中在创建类时会自动给添加注释打开idea,操作Fil
- 为了打造流畅的用户导航体验,我们不得不依赖智能手机最常见的一个功能:触摸。触摸改变应用程序的视图是现在最流行一种导航设计。在本文中,我们将经
- AES简介AES(The Advanced Encryption Standard)是美国国家标准与技术研究所用于加密电子数据的规范。它被预
- 树的同构备忘!定义:给定两棵树r1、r2,如果r1可以通过若干次的左子树和右子树互换,使之与r2完全相同,这说明两者同构。举例树的构造树可以
- 全面解析java注解Java中的常见注解 a.JDK中的注解 @Override 覆盖父类或者父接口的方
- 实现GridView的横向滚动效果如下图:具体实现的代码•1. 主界面布局代码:activity_main.xml<?xml vers
- Random类 (java.util) Ran
- 本文实例讲述了Android创建或升级数据库时执行的语句,如果是创建或升级数据库,请使用带List参数的构造方法,带SQL语句的构造方法将在
- JSON数据格式简洁,用于数据的持久化和对象传输很实用。最近在做一个Razor代码生成器,需要把数据库的表和列的信息修改后保存下来,想到用J
- 指定委托那些办理者处理任务节点,也就是只有此办理者才有操作此节点的操作权限1、直接指定流程图配置实现:在流程图属性栏设置Assignee属性
- 前言数据驱动测试是相同的测试脚本使用不同的测试数据执行,测试数据和测试行为完全分离。数据驱动是做自动化测试中很重要的一部分,数据源的方案也是