【ShaderToy】抗锯齿相关函数

*示例代码可以直接在ShaderToy中运行。

先上未抗锯齿的两个圆形图案,可以清楚看清图案边缘像素块,即“锯齿”。

附代码:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 r =  2.0*vec2(fragCoord.xy - 0.5*iResolution.xy)/iResolution.y;
      vec2 center1 = vec2(-0.75,0);
    vec2 center2 = vec2(0.75,0);

    vec3 bgcol = vec3(1.0,0.5,0.5);//bg color
    vec3 col1 = vec3(0.4,0.6,0.6);//circle1
    vec3 col2 = vec3(0.4,0.2,0.5);//circle2
    vec3 pixel;

    pixel = bgcol;

    if(length(r-center1)<0.4)
        pixel = col1;

    if(length(r-center2)<0.4)
        pixel = col2;

    fragColor = vec4(pixel,1.0);
}

要消除锯齿,这里借助几个GLSL内置函数,下面一个一个做笔记QAQ:

①mix()函数

原型:

//x为下限,y为上限,a为权重
//mix函数返回以a为权重,(x,y)为范围的线性插值
//返回值计算公式:x ×(1?a)+y×a

float mix(float x, float y, float a)
vec2 mix(vec2 x, vec2 y, vec2 a)
vec3 mix(vec3 x, vec3 y, vec3 a)
vec4 mix(vec4 x, vec4 y, vec4 a)

②clamp函数:

原型:

//返回值计算公式:
//      min(max(x, minVal), maxVal)//超出下界即等于下界//超出上界即等于上界
float clamp(float x, float minVal, float maxVal)
vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal)
vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal)
vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal)

③smoothstep函数:

原型:

//在x、y间进行Hermite插值
//等价代码:
//  genType t;
//  t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
//  return t * t * (3.0 - 2.0 * t);

float smoothstep(float edge0, float edge1, float x)
vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x)
vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x)
vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x)

④step函数:

原型:

//step函数返回小于edge的值,否则返回1

float step(float edge, float x)
vec2 step(vec2 edge, vec2 x)
vec3 step(vec3 edge, vec3 x)
vec4 step(vec4 edge, vec4 x)

下面用一个简单明了的小例子来体现mix等函数的功能:

代码如下:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = fragCoord.xy / iResolution.xy;
    vec3 col1 = vec3(1.0,0.2,0.4);
    vec3 col2 = vec3(0.4,0.6,1.0);
    vec3 pixel;
    float m;

    //area 1
    //展示用作示例的两种颜色
    if(p.x<0.2){
        if(p.y<0.5)
            pixel = col1;
        else
            pixel = col2;
    }
    //area 2
    //step函数效果
    else if(p.x<0.4){
        m = step(0.5,p.y);
        pixel = mix(col1,col2,m);

    }
    //area 3
    //根据纵坐标数值线性变化效果
    else if(p.x<0.6){
        m = p.y;
        pixel = mix(col1,col2,m);
    }

    //area 4
    //clamp函数效果
    else if(p.x<0.8){
        m = clamp(p.y,0.4,0.8);//即将线性变化区间从完整的[0,1]变成[0.4,0.8]
        pixel = mix(col1,col2,m);
    }
    //area 5
    //smoothstep函数效果
    else{
        m = smoothstep(0.45, 0.55, p.y);
        pixel = mix(col1,col2,m);
    }
    //区域分界线
    for(float i=0.2;i<1.0;i += 0.2){
        if(p.x<i&&p.x>i-0.005)
            pixel = vec3(1.0);
    }

    fragColor = vec4((pixel),1.0);
}

回到最初的圆形。

用上述函数对原始圆形图案进行处理,弱化锯齿:

附代码:

float linearstep(float edge0, float edge1, float x) {
    float t = (x - edge0)/(edge1 - edge0);
    return clamp(t, 0.0, 1.0);
}

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 mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 r =  2.0*vec2(fragCoord.xy - 0.5*iResolution.xy)/iResolution.y;
    vec3 bgcol = vec3(1.0,0.3,0.5);//bg color
    vec3 col1 = vec3(0.4,0.2,0.5);//circle
    vec2 center1 = vec2(-1.35,0);
    vec2 center2 = vec2(-0.45,0);
    vec2 center3 = vec2(0.45,0);
    vec2 center4 = vec2(1.35,0);
    vec3 pixel = bgcol;
    float m=0.4;

    pixel = bgcol; 

    //circle 0
    //未经任何处理
    /*
    if(r.x<-0.9){
        if(length(r-center1)<m){
            pixel = col1;
        }
    }
    */

    //circle 1
    //step处理,等同于未经任何处理的circle 0
    if(r.x<-0.9){
        m =  step(m,length(r-center1));
        pixel = mix(col1,bgcol,m);
    } 

    //circle 2
    //linearstep处理
    else if(r.x<-0.0){
        m =  linearstep(m-0.005,m+0.005,length(r-center2));
        pixel = mix(col1,bgcol,m);
    }

    //circle 3
    //smoothstep处理
    else if(r.x<0.9){
           m =  smoothstep(m-0.005,m+0.005,length(r-center3));
        pixel = mix(col1,bgcol,m);
    }

    //circle 4
    //自定义smootherstep处理
    else if(r.x<1.8){
           m =  smootherstep(m-0.005,m+0.005,length(r-center4));
        pixel = mix(col1,bgcol,m);
    }

    //区域分解线
    for(float i=-0.9;i<2.0;i += 0.9){
        if(r.x<i&&r.x>i-0.005)
            pixel = vec3(1.0);
    }

    fragColor = vec4(pixel,1.0);
}

上图可能不太明显,在shadertoy网站运行代码全屏会更清楚点。事实是从左到右四个图的圆形锯齿越来越不明显。

这里有段代码蛮有意思的:

float t = (x - edge0)/(edge1 - edge0);
return clamp(t, 0.0, 1.0);

第一行代码的作用是判断x和edge1之间的关系,结合第二行clamp函数,如果>1说明x>edge1;如果<1则反之。

【over.】

时间: 2025-01-13 10:30:07

【ShaderToy】抗锯齿相关函数的相关文章

【ShaderToy】基础篇之再谈抗锯齿(antialiasing,AA)

写在前面 在之前的基础篇中,我们讲到了在绘制点线时如何处理边缘的锯齿,也就是使用smoothstep函数.而模糊参数是一些定值,或者是跟屏幕分辨率相关的数值,例如分辨率宽度的5%等等.但这种方法其实是有一种问题的.这需要我们从绘制的图像说起. ShaderToy中绘制的很多图像可以说是一种Procedure Texture,过程纹理,即是计算机生成的纹理.拿之前画的圆和线来说,这些圆和线的绘制过程,是我们计算每个fragment到"期望图像"的距离,然后根据距离来判断使用哪种颜色.如果

SSE图像算法优化系列二十四: 基于形态学的图像后期抗锯齿算法--MLAA优化研究。

偶尔看到这样的一个算法,觉得还是蛮有意思的,花了将近10天多的时间研究了下相关代码. 以下为百度的结果:MLAA全称Morphological Antialiasing,意为形态抗锯齿是AMD推出的完全基于CPU处理的抗锯齿解决方案.对于游戏厂商使用的MSAA抗锯齿技术不同,Intel最新推出的MLAA将跨越边缘像素的前景和背景色进行混合,用第2种颜色来填充该像素,从而更有效地改进图像边缘的变现效果,这就是MLAA技术. 其实就是这个是由Intel的工程师先于2009年提出的技术,但是由AMD将

移动端canvas抗锯齿

未抗锯齿效果图: 加入抗锯齿代码效果: var Game = function(){ var H = document.documentElement.clientHeight || document.body.clientHeight; var W = document.documentElement.clientWidth || document.body.clientWidth; this.canvas = document.getElementById("canvas"); t

OpenGL核心技术之抗锯齿

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解>电子工业出版社等. CSDN视频网址:http://edu.csdn.net/lecturer/144 抗锯齿问题在游戏中一直存在的,尤其是体现在3D模型上的材质或者游戏UI界面上,由于现在引擎都非常完善,并且引擎都提供了抗锯齿功能,我们通过引擎提供的参数界面设置一下就可以消除.但是很

GPU抗锯齿

抗锯齿(Anti-aliasing):标准翻译为"抗图像折叠失真".由于在3D图像中,受分辨的制约,物体边缘总会或多或少的呈现三角形的锯齿,而抗锯齿就是指对图像边缘进行柔化处理,使图像边缘看起来更平滑,更接近实物的物体.它是提高画质以使之柔和的一种方法.如今最新的全屏抗锯齿(FullSceneAnti-Aliasing)可以有效的消除多边形结合处(特别是较小的多边形间组合中)的错位现象,降低了图像的失真度.全景抗锯齿在进行处理时,须对图像附近的像素进行2-4次采样,以达到不同级别的抗锯

回击MLAA:NVIDIA FXAA抗锯齿性能实测、画质对比

PC游戏玩家肯定会对各式各样的AA抗锯齿技术非常熟悉,而今天本文的主角就是NVIDIA今年才推出的新型抗锯齿技术"FXAA". FXAA在某种程度上有些类似于AMD之前宣传的MLAA(形态抗锯齿),但远比后者低调,所以很多玩家可能还从来没听说过,但是如果你玩过<永远的毁灭公爵>或者<F.3.A.R>,应该会有所耳闻.今天我们就来实际测测多款显卡上的FXAA性能和画质表现,并将其与MLAA进行简单对比. 什么是FXAA? FXAA全称为"Fast App

未来抗锯齿,FXAA/TXAA

前言:未来抗锯齿,FXAA/TXAA回顶部 [PConline 应用]在3D图像中,我们不可避免的遇到"锯齿".锯齿是由于受到显示设备分辨率和图像生成原理制约,不可避免的会出现的一种图像失真现象,具体表现为画面中物体的边缘呈现出直角的锯齿状.为了获得更好的视觉体验,让物体边缘看起来更柔和.自然,需要进行消除锯齿(Anti-Aliasing,简称AA)处理. 未来抗锯齿技术的方向:FXAA/TXAA 虽然抗锯齿了,但是模糊了 虽然FSAA全屏抗锯齿技术十分成熟,但是无论怎样发展,是不能够

OpenGL中的抗锯齿技术

计算机通过离散(不连续)的像素来绘制图形,想象一下,真实世界中,我们画直线,是比连续画的,还是一个点一个点画的?计算机就是一个点一个点画的(很小的矩形).这样就会导致绘制的图形走样(锯齿),消除锯齿的技术就叫反走样(抗锯齿) 可以看这篇:http://blog.csdn.net/mikewolf2009/archive/2009/08/18/4460421.aspx 点示例 当点很大时,显示如下 而我们实际想看到的是一个圆点,而不是矩形 启用抗锯齿后的效果 有点圆了 代码 glPointSize

抗锯齿说

抗锯齿处理依赖混合处理,借助混合处理功能. #include <GL/glut.h> static float rotAngle =0.; #include <stdio.h> void init(void){ GLfloat values[2]; glGetFloatv(GL_LINE_WIDTH_GRANULARITY,values); printf("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n",values[0]