粒子系统的顶点着色器

时间:2015-11-01 11:00:32

标签: c++ glsl fragment-shader vertex-shader

我正在使用OpenGL中的简单粒子系统;到目前为止,我已经编写了两个片段着色器来更新速度和位置以响应我的鼠标,它们似乎工作!我已经看过这两个纹理了,它们似乎都做出了正确的反应(从随机噪音到有序的结构,以响应我的鼠标)。

但是,我对如何绘制粒子有疑问。我对顶点着色器很新(之前只使用过片段着色器);我的理解是通常的方法是像这样的顶点着色器:

uniform sampler2DRect tex;
varying vec4 cur;

void main() {
    gl_FrontColor = gl_Color;
    cur = texture2DRect(tex, gl_Vertex.xy);
    vec2 pos = cur.xy;
    gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 0., 1.);
}

根据位置缓冲区中的值将坐标转换为适当的位置。但是,当我运行它时,我得到gl错误,它无法编译 - 经过一些研究,似乎不推荐使用gl_ModelViewProjectionMatrix。

现在不推荐使用模型视图矩阵,这样做的正确方法是什么?我不想尝试透视任何东西,我只需要一个普通的纹理正交视图。

谢谢!

1 个答案:

答案 0 :(得分:2)

您使用的是什么版本的GLSL(没有看到任何#version指令)?是的,我认为gl_ModelViewProjectionMatrix确实已被弃用。但是,如果您想使用它,this可能有所帮助。顺便说一句,varying限定词也很老。我宁愿使用inout限定符,它会使着色器代码更具“可读性”。

'正确'的方法是创建自己的矩阵 - 模型和视图(例如使用glm库)并将它们相乘,然后将它们作为统一传递给着色器。可以找到带有示例的教程here

这是我用于显示纹理的vs着色器(全屏四边形):

#version 430

layout(location = 0) in vec2 vPosition;
layout(location = 1) in vec2 vUV;

out vec2 uv;

void main()
{
    gl_Position = vec4(vPosition,1.0,1.0);
    uv = vUV;
}

片段着色器:

#version 430

in vec2 uv;
out vec4 final_color;
uniform sampler2D tex;

void main()
{
    final_color = texture(tex, uv).rgba;
}

这里是我的坐标(我的坐标是静态的,但你可以更改它并更新缓冲区 - 着色器可以是相同的):

//Quad verticles - omitted z coord, because it will always be 1
float pos[] = {
    -1.0, 1.0,
    1.0, 1.0,
    -1.0, -1.0,
    1.0, -1.0
};

float uv[] = {
    0.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0
};

也许您可以在执行此着色器glDisable(GL_DEPTH_TEST);

之前尝试关闭深度比较