Android OpenGL ES绘制小圆点

需求与思路

需要绘制很多小圆点,如果用三角形拼接的方式来画圆的话,绘制比较大的圆用三角形的方式是可以的,但是如果只是绘制很小的圆点用三角形就很别扭了,也不是最佳的实现方式,因此想到用Point的方式绘制,但是Point的方式绘制出来是正方形的,所以需要特别的处理使之变成圆点。这里通过在fragment shader里判断如果当前绘制的fragment的位置超过Point绘制方式的最大内接圆的半径的时候discard该fragment。

效果图

Android OpenGL ES绘制小圆点_第1张图片
大体效果为上图,这里写在fragment shader的判断语句为length(gl_PointCoord - vec2(0.5)) > 0.5时,discard该片元。详细代码如下:
#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fragColor;
void main() {
    if (length(gl_PointCoord - vec2(0.5)) > 0.5) {
        discard;
    }
    fragColor = vColor;
}
这里有些变量稍微说一下,gl_PointCoord是只有在当绘制图元为点的时候才会有值,当为其它图元时是未定义的。还有一个gl_FragCoord这个值是fragment相对于坐标系的值。还有一点是在opengl es 3.x里,fragment shader输出的颜色值是自己定义的out输出,并不是opengl es 2.0里的gl_FragColor内置变量。

优化

如果仔细看的话可以看到有锯齿,这里主要对锯齿进行优化。这里锯齿比较明显是因为当gl_PointCoord超过值的时候是直接丢弃掉的,就像step函数一样,值是直接跳变的,因此我们改为用smoothstep来进行边界处的平滑处理。具体代码如下:
#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fragColor;
void main() {
    float dist = length(gl_PointCoord - vec2(0.5));
    float value = -smoothstep(0.48, 0.5, dist) + 1.0;
    if (value == 0.0) {
        discard;
    }
    fragColor = vec4(vColor.r, vColor.g, vColor.b, vColor.a * value);
}
优化的对比效果图如下:
Android OpenGL ES绘制小圆点_第2张图片
绿色的那一排第一个是用三角形的方式绘制的圆,第二个是未优化的圆点,第三个是经过优化的点,视觉上看优化还是很明显的。

源码下载

附上源码的下载路径: http://download.csdn.net/download/soely/10204448,此源码是Android Studio里的一份Module,因此你可以在你的Project里Import Module的方式直接的导入。

你可能感兴趣的:(OpenGL)