使用GLSL直接从着色器中的位置计算平移mattrix 我在C++ OpenGL程序和GLSL顶点和片段着色器上学习。

使用GLSL直接从着色器中的位置计算平移mattrix 我在C++ OpenGL程序和GLSL顶点和片段着色器上学习。,c++,opengl,glsl,glm-math,coordinate-transformation,C++,Opengl,Glsl,Glm Math,Coordinate Transformation,我正在创建同一对象的多个实例。我只需要在实例之间更改对象位置 以下是我所做的:我正在处理一个统一变量,它是一个变换矩阵数组。每个矩阵代表一个对象实例 MVP也是一个变换矩阵,但MVP是由摄影机位置、方向和属性设置的 这是我的顶点着色器: #version 330 core layout(location = 0) in vec3 vertex_position; layout(location = 1) in vec3 vertex_color; uniform

我正在创建同一对象的多个实例。我只需要在实例之间更改对象位置

以下是我所做的:我正在处理一个统一变量,它是一个变换矩阵数组。每个矩阵代表一个对象实例

MVP也是一个变换矩阵,但MVP是由摄影机位置、方向和属性设置的

这是我的顶点着色器:

    #version 330 core
    layout(location = 0) in vec3 vertex_position;
    layout(location = 1) in vec3 vertex_color;

    uniform mat4 object_positions[20];
    out vec3 fragment_color;
    uniform mat4 MVP;

    void main()
    {
        gl_Position = object_positions[gl_InstanceID] * MVP * vec4(vertex_position,1.0);
        fragment_color = vertex_color;
    }
这是我在C++程序中要设置的对象位置:

    glm::mat4 object_positions[20];
    object_positions[0] = glm::translate(glm::mat4(1), glm::vec3(0.4f,0.2f,0.0f));
    object_positions[1] = glm::translate(glm::mat4(1), glm::vec3(0.5f,1.4f,0.0f));
    ...
    object_positions[19] = glm::translate(glm::mat4(1), glm::vec3(-10.6f,0.2f,0.0f)); 
    GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
    ...
    glUniformMatrix4fv(object_positions_id, 7, GL_FALSE, glm::value_ptr(object_positions[0]));
您看到的glm::translate的第二个参数vec3包含每个对象位置。 在这一点上,一切都很顺利

我想做的是计算着色器中glm::Translate的值。事实上,我想要的是为每个职位发送vec3而不是mat4。我希望GPU计算转换矩阵,而不是CPU。我尝试的一切都不起作用


感谢

,因为OpenGL转换矩阵只是16个条目的一维数组(说到4X4矩阵)。在这个矩阵中,第13、14、15项定义了翻译组件。因此,如果以行主形式存储矩阵,则第4行第0、第1和第2项应为发送到着色器的向量x、y、z分量。可以用这种方法在着色器中构建转换矩阵。请确保,如果您有行主矩阵,那么要变换顶点,请按矩阵进行预乘,以查看平移效果

   gl_Position = Translation Matrix * gl_Vertex;

如果您的矩阵是列主矩阵,您将发布乘法

对于OpenGL,转换矩阵只是16个条目的一维数组(说到4X4矩阵)。在这个矩阵中,第13、14、15项定义了翻译组件。因此,如果以行主形式存储矩阵,则第4行第0、第1和第2项应为发送到着色器的向量x、y、z分量。可以用这种方法在着色器中构建转换矩阵。请确保,如果您有行主矩阵,那么要变换顶点,请按矩阵进行预乘,以查看平移效果

   gl_Position = Translation Matrix * gl_Vertex;

如果您的矩阵是列主矩阵,您将发布乘法

4*4矩阵如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));
在GLSL中,a
mat4 m的列的地址如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));
可以在顶点着色器中设置
mat4
,如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));

但是,如果只希望通过偏移操作顶点位置,则不需要变换矩阵。可以简单地将偏移添加到顶点位置(前提是偏移是笛卡尔坐标而不是齐次坐标,如您的情况所示):


你必须这样穿制服:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));

进一步见:


4*4矩阵如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));
在GLSL中,a
mat4 m的列的地址如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));
可以在顶点着色器中设置
mat4
,如下所示:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));

但是,如果只希望通过偏移操作顶点位置,则不需要变换矩阵。可以简单地将偏移添加到顶点位置(前提是偏移是笛卡尔坐标而不是齐次坐标,如您的情况所示):


你必须这样穿制服:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx  Yx  Zx  Tx ]        [  0   4   8  12 ]     
[ Xy  Yy  Zy  Ty ]        [  1   5   9  13 ]     
[ Xz  Yz  Zz  Tz ]        [  2   6  10  14 ]     
[  0   0   0   1 ]        [  3   7  11  15 ] 
vec4 c0 = m[0].xyzw;
vec4 c1 = m[1].xyzw;
vec4 c2 = m[2].xyzw;
vec4 c3 = m[3].xyzw;
#version 330 core
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;

out vec3 fragment_color;
uniform mat4 MVP;

uniform vec3 object_positions[20];

void main()
{
    mat4 posMat = mat4(
        vec4( 1.0, 0.0, 0.0, 0.0),
        vec4( 0.0, 1.0, 0.0, 0.0),
        vec4( 0.0, 0.0, 1.0, 0.0),
        vec4( object_positions[gl_InstanceID], 1.0) );

    gl_Position = MVP * posMat * vec4(vertex_position,1.0);
    fragment_color = vertex_color;
}
glm::vec3 object_positions[20];
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f);
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f);
...
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions");
...
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0]));

进一步见:


你绝对不能做
对象位置[gl\u InstanceID]*MVP*vec4(顶点位置,1.0)(即使对象位置是矩阵),因为在应用投影矩阵后,这将进行平移

如果您没有对实例进行任何旋转,那么没有理由不这样做

 gl_Position = MVP * vec4(vertex_position + object_positions[gl_InstanceID],1.0);

你绝对不能做
对象位置[gl\u InstanceID]*MVP*vec4(顶点位置,1.0)(即使对象位置是矩阵),因为在应用投影矩阵后,这将进行平移

如果您没有对实例进行任何旋转,那么没有理由不这样做

 gl_Position = MVP * vec4(vertex_position + object_positions[gl_InstanceID],1.0);

不,它不起作用。这是完全相同的结果。在这种情况下,对象位置应该是一个变换矩阵,而不是一个位置。为什么只添加偏移量就需要一个矩阵更简单、更快?是的,这是一个好主意,但我应该在w中添加什么?这很奇怪,我尝试添加w=0,位置似乎是按2划分的。为什么要设置
w=0
?你把
w
单独留下。您的输入
w
在该着色器中保证为1.0,因此您可以直接在
xyz
中应用偏移量。不,它不起作用。这是完全相同的结果。在这种情况下,对象位置应该是一个变换矩阵,而不是一个位置。为什么只添加偏移量就需要一个矩阵更简单、更快?是的,这是一个好主意,但我应该在w中添加什么?这很奇怪,我尝试添加w=0,位置似乎是按2划分的。为什么要设置
w=0
?你把
w
单独留下。您的输入
w
在该着色器中保证为1.0,因此您可以直接在
xyz
中应用偏移量。
posMat*vec4(顶点位置,1.0)
不等于
vec4(对象位置[gl\u实例ID]+顶点位置,1.0)
?不是
posMat*vec4(顶点位置,1.0)
仅相当于
vec4(对象位置[gl\U实例ID]+顶点位置,1.0)