过程纹理和抗锯齿:ProceduralTexture & Anti aliasing - MartinRGB/GLES30_ProgrammingGuide_NDK GitHub Wiki
过程纹理
以过程而非图像描述的纹理,描述了给定输入,生成纹理颜色或深度值的算法
优点:小,不损失细节
缺点:占用指令带宽,可能有锯齿。
Vert:
void main() {
v_st = a_texcoord;
gl_Position = mvp_matrix * vec4( position, 1.0 );
}
Frag:
void main() {
vec2 texcoord = mod(floor(v_st * float(u_frequency *2)),2.0);
float delta = abs(texcoord.x - texcoord.y);
gl_FragColor = mix(vec4(0.,1.,0.,1.),vec4(1.,0.,0.,1.),delta);
}
抗锯齿
为了防止抗锯齿,需要估计像素覆盖区域的平均纹理值。OpenGL ES 包含了导数函数 dFdx
dFdy
计算 函数在 x y 的变化率,称之为 梯度向量。fwidth
可以计算出梯度向量的幅度。
在上个粒子中,可以用 fwidth计算出v_st.x v_st.y的过滤宽度
假设过滤宽度w,过滤宽度最小值k:
1.w < k/2,不产生锯齿,使用 smoothstep 在真正的函数和平均值之间渐变。
2.w > k/2 会产生锯齿,使用函数平均值。
Frag:
vec4 color;
vec4 color0 = vec4(1.,0.,0.,1.);
vec4 color1 = vec4(0.,1.,0.,1.);
vec2 st_width;
vec2 fuzz;
vec2 check_pos;
float fuzz_max;
st_width = fwidth(v_st);
fuzz = st_width * float(u_frequency) * 2.0;
fuzz_max = max(fuzz.s,fuzz.t);
check_pos = fract(vUv * float(u_frequency));
// w < k/2,不产生锯齿,使用 smoothstep 在真正的函数和平均值之间渐变。
if(fuzz_max <=0.5){
vec2 p = smoothstep(vec2(0.5),fuzz+vec2(0.5),check_pos) + (1.0 - smoothstep(vec2(0.),fuzz,check_pos));
color = mix(color0,color1,p.x*p.y+(1.0-p.x)*(1.0-p.y));
color = mix(color,(color0+color1)/2.0,smoothstep(0.125,0.5,fuzz_max));
}
// w > k/2,产生锯齿,使用平均值
else
{
color = (color0+color1)/2.0;
}
gl_FragColor = color;