标签:val size step 结合 1.0 near 全屏 line float
*示例代码可以直接在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.】
标签:val size step 结合 1.0 near 全屏 line float
原文地址:http://www.cnblogs.com/liez/p/6917186.html