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