简体   繁体   English

如何在iOS OpenGL ES 2.0中画星

[英]How to draw a star in iOS OpenGL ES 2.0

This question has been asked before but the quite a few years ago in my searches. 这个问题以前已经有人问过,但是几年前我才问过。 The answer was always to use texture mapping but what I really want to do is represent the star as a single vertex - you may think I'm copping out with a simplistic method but in fact, a single point source of light actually looks pretty good and realistic. 答案总是使用纹理映射,但是我真正想做的是将恒星表示为单个顶点-您可能认为我正在用一种简单的方法来解决问题,但实际上,单点光源实际上看起来还不错和现实。 But I want to process that point of light with something like a gaussian blur too give it a little more body when zooming in or for brighter stars. 但是我想用高斯模糊之类的东西来处理那个光点,在放大或寻找更明亮的恒星时也要给它更多的身体。 I was going to texture map a gaussian blur image but if I understand things correctly I would then have to draw each star with 4 vertexes. 我本来要对高斯模糊图像进行纹理贴图,但是如果我对事情的理解正确,那么我将不得不用4个顶点绘制每个星星。 Maybe not so difficult but I don't want to go there if I can just process a single vertex. 也许没有那么困难,但是如果我只能处理一个顶点,我就不想去那里。 Would a vertex-shader do this? 顶点着色器会这样做吗? Can GLKBaseEffects get me there? GLKBaseEffects可以带我到那里吗? Any suggestions? 有什么建议么?

Thanks. 谢谢。

You can use point sprites. 您可以使用点精灵。

Draw Calls 抽签

You use a texture containing the image of the star, and use the typical setup to bind a texture, bind it to a sampler uniform in the shader, etc. 您使用包含星星图像的纹理,并使用典型的设置来绑定纹理,将其绑定到着色器中均匀的采样器等。

You draw a single vertex for each star, with GL_POINTS as the primitive type passed as the first argument to glDrawArrays() / glDrawElements() . 您为每个星星绘制一个顶点,并以GL_POINTS作为基本类型作为第一个参数传递给glDrawArrays() / glDrawElements() No texture coordinates are needed. 不需要纹理坐标。

Vertex Shader 顶点着色器

In the vertex shader, you transform the vertex as you normally would, and also set the built-in gl_PointSize variable: 在顶点着色器中,您可以像通常那样变换顶点,并设置内置的gl_PointSize变量:

uniform float PointSize;
attribute vec4 Position;

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

For the example, I used a uniform for the point size, which means that all stars will have the same size. 对于该示例,我为点大小使用了统一的大小,这意味着所有恒星将具有相同的大小。 Depending on the desired effect, you could also calculate the size based on the distance, or use an additional vertex attribute to specify a different size for each star. 根据所需的效果,您还可以根据距离计算大小,或使用其他顶点属性为每颗恒星指定不同的大小。

Fragment Shader 片段着色器

In the fragment shader, you can now access the built-in gl_PointCoord variable to get the relative coordinates of the fragment within the point sprite. 在片段着色器中,您现在可以访问内置的gl_PointCoord变量,以获取点精灵中片段的相对坐标。 If your point sprite is a simple texture image, you can use it directly as the texture coordinates. 如果点精灵是简单的纹理图像,则可以将其直接用作纹理坐标。

uniform sampler2D SpriteTex;

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

Additional Material 附加材料

I answered a somewhat similar question here: Render large circular points in modern OpenGL . 我在这里回答了一个类似的问题: 在现代OpenGL中渲染大圆形点 Since it was for desktop OpenGL, and not for a textured sprite, this seemed worth a separate answer. 由于它是用于桌面OpenGL的,而不是用于纹理Sprite的,因此似乎值得单独回答。 But some of the steps are shared, and might be explained in more detail in the other answer. 但是某些步骤是共享的,可能在其他答案中有更详细的说明。

I've been busy educating myself on this and trying it but I'm getting strange results. 我一直在忙着自我教育和尝试,但是结果却很奇怪。 It seems to work with regard to vertex transform - because I see the points moved out on the screen - but pointsize and colour are not being affected. 对于顶点变换,这似乎可行-因为我看到了点在屏幕上的移出-但是点的大小和颜色没有受到影响。 The colour seems to be some sort of default yellow colour with some shading between vertices. 该颜色似乎是某种默认的黄色,在顶点之间有一些阴影。

What bothers me too is that I get error messages on built-ins in the vertex shader. 同样困扰我的是,我在顶点着色器中的内置组件上收到错误消息。 Here are the vertex/fragment code and the error messages: 以下是顶点/片段代码和错误消息:

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

Here's the error message: 这是错误消息:

ERROR: 0:24: Use of undeclared identifier 'gl_ModelViewMatrix' ERROR: 0:24: Use of undeclared identifier 'gl_Vertex' ERROR: One or more attached shaders not successfully compiled 错误:0:24:使用未声明的标识符'gl_ModelViewMatrix'错误:0:24:使用未声明的标识符'gl_Vertex'错误:一个或多个附加着色器未成功编译

It seems the transform is being passed from my iOS code where I'm using GLKBaseEffects such as in the following lines: 似乎是从我使用GLKBaseEffects的iOS代码传递了转换,如以下几行:

self.effect.transform.modelviewMatrix = modelViewMatrix;

[self.effect prepareToDraw];

But I'm not sure exactly whats happening, especially with the shader compile errors. 但是我不确定到底发生了什么,尤其是着色器编译错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM