使用GLSL直接从着色器中的位置计算平移mattrix 我在C++ OpenGL程序和GLSL顶点和片段着色器上学习。
我正在创建同一对象的多个实例。我只需要在实例之间更改对象位置 以下是我所做的:我正在处理一个统一变量,它是一个变换矩阵数组。每个矩阵代表一个对象实例 MVP也是一个变换矩阵,但MVP是由摄影机位置、方向和属性设置的 这是我的顶点着色器:使用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
#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中,amat4 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中,amat4 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)
?