如何在iOS OpenGL ES 2.0中绘制一颗星星

这个问题之前已被问到,但是几年前我的搜索中也是如此。 答案总是使用纹理映射,但我真正想做的是将星形表示为单个顶点 – 你可能认为我正在用一种简单的方法来实现,但事实上,单点光源实际上看起来相当不错和现实的。 但是我希望用高斯模糊处理那个光点,在放大或者更亮的星星时给它更多的身体。 我打算将高斯模糊图像纹理化,但如果我理解正确的话,那么我必须用4个顶点绘制每个恒星。 也许不是那么困难,但如果我能处理一个顶点,我不想去那里。 顶点着色器会这样做吗? GLKBaseEffects能让我在那里吗? 有什么建议么?

谢谢。

你可以使用点精灵。

画电话

您使用包含星形图像的纹理,并使用典型设置绑定纹理,将其绑定到着色器中的采样器制服等。

您为每个星形绘制一个顶点, GL_POINTS作为原始类型作为glDrawArrays() / glDrawElements()的第一个参数传递。 不需要纹理坐标。

顶点着色器

在顶点着色器中,您可以像往常一样转换顶点,还可以设置内置的gl_PointSize变量:

 uniform float PointSize; attribute vec4 Position; void main() { gl_Position = ...; // Transform Position attribute; gl_PointSize = PointSize; } 

例如,我使用了一个统一的点大小,这意味着所有的星星都具有相同的大小。 根据所需的效果,您还可以根据距离计算大小,或使用其他顶点属性为每个星指定不同的大小。

片段着色器

在片段着色器中,您现在可以访问内置的gl_PointCoord变量以获取点精灵内片段的相对坐标。 如果您的点精灵是一个简单的纹理图像,您可以直接使用它作为纹理坐标。

 uniform sampler2D SpriteTex; void main() { gl_FragColor = texture2D(SpriteTex, gl_PointCoord); } 

附加材料

我在这里回答了一个类似的问题: 在现代OpenGL中渲染大圆点 。 既然它是用于桌面OpenGL,而不是用于纹理精灵,这似乎值得一个单独的答案。 但是有些步骤是共享的,可能会在另一个答案中更详细地解释。

我一直在忙着教育自己并尝试它,但我得到了奇怪的结果。 它似乎适用于顶点变换 – 因为我看到点在屏幕上移出 – 但点数和颜色不受影响。 颜色似乎是某种默认的黄色,顶点之间有一些阴影。

令我困扰的是我在顶点着色器中获得内置函数的错误消息。 这是顶点/片段代码和错误消息:

 #Vertex shader precision mediump float; precision lowp int; attribute float Pointsize; varying vec4 color_out; void main() { gl_PointSize = Pointsize; gl_Position = gl_ModelViewMatrix * gl_Vertex; color_out = vec4(0.0, 1.0, 0.0, 1.0); // output only green for test } #Fragment shader precision mediump float; precision lowp int; varying vec4 color_out; void main() { gl_FragColor = color_out; } 

这是错误消息:

错误:0:24:使用未声明的标识符’gl_ModelViewMatrix’错误:0:24:使用未声明的标识符’gl_Vertex’错误:一个或多个连接的着色器未成功编译

似乎转换是从我的iOS代码传递的,我正在使用GLKBaseEffects,如下面的行:

 self.effect.transform.modelviewMatrix = modelViewMatrix; [self.effect prepareToDraw]; 

但我不确定到底发生了什么,尤其是着色器编译错误。