顶点着色器不适用于克隆对象
Vertex shader doesn't work well with cloned objects
我正在使用 OpenGL 创建一个球体(近似值):
我是 "inflating" 创建八个球体的三角形:
然后我将那个八分圆绘制四次,每次将模型转换旋转 90°,以获得一个半球:
绘图调用相关代码:
for (int i = 0; i < 4; i++) {
model_trans = glm::rotate(model_trans, glm::radians(i * 90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(model_trans));
glDrawElementsBaseVertex(GL_TRIANGLES, sizeof(sphere_indices) / sizeof(sphere_indices[0]),
GL_UNSIGNED_INT, 0, (sizeof(grid_vertices)) / (ATTR_COUNT * sizeof(GLfloat)));
}
我的目标是根据顶点在 XY 平面中的投影角度为每个顶点着色。由于我正在对值进行归一化,因此生成的投影应该表现得像一个三角圆,x 值是与 x 轴正端的角度的余弦值。因为余弦是一个连续函数,我的球体也应该有连续的颜色。然而,事实并非如此:
这个问题是克隆对象引起的吗?这是我唯一能想到的,但这无关紧要,因为顶点着色器只接收单个顶点。说到这里,这是我的顶点着色器:
#version 150 core
in vec3 position;
/* flat : the color will be sourced from the provoking vertex. */
flat out vec3 Color;
/* transformation matrices */
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
vec3 vector_proj = vec3(position.x, position.y, 0.0);
normalize(vector_proj);
/* Addition and division only for mapping range [-1, +1] to [0, 1] */
float cosine = (vector_proj.x + 1) / 2;
Color = vec3(cosine);
}
您想从顶点位置的世界坐标计算与顶点关联的颜色。
position
是模型坐标,不是世界坐标。在计算 vector_proj
:
之前,您必须将模型矩阵应用于 position
以从模型 space 转换为世界 space
vec4 world_pos = model * vec4(position, 1.0);
vec3 vector_proj = vec3( world_pos.xy, 0.0 );
normalize
的参数不是输入输出参数。它是一个输入参数,函数返回归一化结果:
vector_proj = normalize(vector_proj);
您可以简化代码如下:
void main()
{
vec4 world_pos = model * vec4(position, 1.0);
gl_Position = projection * view * world_pos;
vec2 vector_proj = normalize(world_pos.xy);
/* Addition and division only for mapping range [-1, +1] to [0, 1] */
float cosine = (vector_proj.x + 1) / 2;
Color = vec3(cosine);
}
我正在使用 OpenGL 创建一个球体(近似值):
我是 "inflating" 创建八个球体的三角形:
然后我将那个八分圆绘制四次,每次将模型转换旋转 90°,以获得一个半球:
绘图调用相关代码:
for (int i = 0; i < 4; i++) {
model_trans = glm::rotate(model_trans, glm::radians(i * 90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(model_trans));
glDrawElementsBaseVertex(GL_TRIANGLES, sizeof(sphere_indices) / sizeof(sphere_indices[0]),
GL_UNSIGNED_INT, 0, (sizeof(grid_vertices)) / (ATTR_COUNT * sizeof(GLfloat)));
}
我的目标是根据顶点在 XY 平面中的投影角度为每个顶点着色。由于我正在对值进行归一化,因此生成的投影应该表现得像一个三角圆,x 值是与 x 轴正端的角度的余弦值。因为余弦是一个连续函数,我的球体也应该有连续的颜色。然而,事实并非如此:
这个问题是克隆对象引起的吗?这是我唯一能想到的,但这无关紧要,因为顶点着色器只接收单个顶点。说到这里,这是我的顶点着色器:
#version 150 core
in vec3 position;
/* flat : the color will be sourced from the provoking vertex. */
flat out vec3 Color;
/* transformation matrices */
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
vec3 vector_proj = vec3(position.x, position.y, 0.0);
normalize(vector_proj);
/* Addition and division only for mapping range [-1, +1] to [0, 1] */
float cosine = (vector_proj.x + 1) / 2;
Color = vec3(cosine);
}
您想从顶点位置的世界坐标计算与顶点关联的颜色。
position
是模型坐标,不是世界坐标。在计算 vector_proj
:
position
以从模型 space 转换为世界 space
vec4 world_pos = model * vec4(position, 1.0);
vec3 vector_proj = vec3( world_pos.xy, 0.0 );
normalize
的参数不是输入输出参数。它是一个输入参数,函数返回归一化结果:
vector_proj = normalize(vector_proj);
您可以简化代码如下:
void main()
{
vec4 world_pos = model * vec4(position, 1.0);
gl_Position = projection * view * world_pos;
vec2 vector_proj = normalize(world_pos.xy);
/* Addition and division only for mapping range [-1, +1] to [0, 1] */
float cosine = (vector_proj.x + 1) / 2;
Color = vec3(cosine);
}