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

时间:2015-01-31 17:07:35

标签: ios opengl-es-2.0 vertex-shader

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

感谢。

2 个答案:

答案 0 :(得分:1)

你可以使用点精灵。

绘制电话

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

为每个星形绘制一个顶点,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);
}

附加材料

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

答案 1 :(得分:0)

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

让我感到困扰的是,我在顶点着色器中收到内置函数的错误消息。以下是顶点/片段代码和错误消息:

#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];

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