zoukankan      html  css  js  c++  java
  • 【ShaderToy】抗锯齿相关函数

    *示例代码可以直接在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.】

  • 相关阅读:
    Disruptor-架构思维的转变
    高性能队列——Disruptor
    flink Standalone Cluster
    Kafka 0.11.0.0 实现 producer的Exactly-once 语义(官方DEMO)
    Kafka 0.11.0.0 实现 producer的Exactly-once 语义(中文)
    Kafka 0.11.0.0 实现 producer的Exactly-once 语义(英文)
    flink window的early计算
    Flink 的Window 操作(基于flink 1.3描述)
    Flink Pre-defined Timestamp Extractors / Watermark Emitters(预定义的时间戳提取/水位线发射器)
    Flink Event Time Processing and Watermarks(文末有翻译)
  • 原文地址:https://www.cnblogs.com/liez/p/6917186.html
Copyright © 2011-2022 走看看