顶点着色器属性位置中的损坏数据
Corrupted data in vertex shader attribute location
由于顶点着色器属性位置中的数据损坏,我的模型看起来被拉伸了
这是顶点着色器代码:
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNormal;
layout (location = 2) in vec2 texCoord;
layout (location = 3) in vec4 boneWeigths;
layout (location = 4) in ivec4 boneIDs;
out vec3 vNormal;
out vec3 fragPos;
out vec2 fragTexCoord;
const int MAX_BONES = 100;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 boneTransforms[MAX_BONES];
void main()
{
mat4 boneTx = boneTransforms[boneIDs[0]] * boneWeigths[0]
+ boneTransforms[boneIDs[1]] * boneWeigths[1]
+ boneTransforms[boneIDs[2]] * boneWeigths[2]
+ boneTransforms[boneIDs[3]] * boneWeigths[3];
vec4 pos = boneTx * vec4(vertPos, 1.0f);
gl_Position = MVP * pos;
vec4 normal = boneTx * vec4(vertNormal, 0.0f);
vNormal = normalize(vec3(M * normal));
fragPos = vec3(M * pos);
fragTexCoord = vec2(texCoord.x, texCoord.y);
}
问题似乎是 boneIDs 中的损坏数据(boneIDs 数据在 CPU 上没有问题,但着色器中的数据已损坏)。我尝试在着色器中对 boneIDs 数据进行硬编码,效果很好。
这是 VAO 的代码:
// create buffers/arrays
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
// load data into vertex buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
unsigned int sz = sizeof(BoneVertex);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(BoneVertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// set the vertex attribute pointers
// vertex Positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)0);
// vertex normals
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(3 * sizeof(float)));
// vertex texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(6 * sizeof(float)));
// bone weights
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(8 * sizeof(float)));
// bone ids
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glBindVertexArray(0);
BoneVertex 结构:
struct BoneVertex
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 textureCoords;
glm::vec4 boneWeights;
glm::ivec4 boneIDs;
}
这很奇怪,因为前 3 个属性数据似乎没有问题。问题在于 boneIDs 和 boneWeights
这在某种程度上与填充有关,以及数据在结构中的排列方式吗?还是我漏掉了什么?
谢谢
boneIDs
是一个整数数据类型的顶点着色器输入:
layout (location = 4) in ivec4 boneIDs;
如果要为积分属性指定通用顶点属性数据,则必须使用glVertexAttribIPointer
(重点关注I
)而不是glVertexAttribPointer
(参见glVertexAttribPointer
).
请注意,type 参数不指定目标属性的类型,它指定源数据数组的元素类型。 glVertexAttribPointer
将源数据数组转换为浮点值,但 glVertexAttribIPointer
指定整数目标属性的数组。
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glVertexAttribIPointer(4, 4, GL_INT, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
由于顶点着色器属性位置中的数据损坏,我的模型看起来被拉伸了
这是顶点着色器代码:
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNormal;
layout (location = 2) in vec2 texCoord;
layout (location = 3) in vec4 boneWeigths;
layout (location = 4) in ivec4 boneIDs;
out vec3 vNormal;
out vec3 fragPos;
out vec2 fragTexCoord;
const int MAX_BONES = 100;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 boneTransforms[MAX_BONES];
void main()
{
mat4 boneTx = boneTransforms[boneIDs[0]] * boneWeigths[0]
+ boneTransforms[boneIDs[1]] * boneWeigths[1]
+ boneTransforms[boneIDs[2]] * boneWeigths[2]
+ boneTransforms[boneIDs[3]] * boneWeigths[3];
vec4 pos = boneTx * vec4(vertPos, 1.0f);
gl_Position = MVP * pos;
vec4 normal = boneTx * vec4(vertNormal, 0.0f);
vNormal = normalize(vec3(M * normal));
fragPos = vec3(M * pos);
fragTexCoord = vec2(texCoord.x, texCoord.y);
}
问题似乎是 boneIDs 中的损坏数据(boneIDs 数据在 CPU 上没有问题,但着色器中的数据已损坏)。我尝试在着色器中对 boneIDs 数据进行硬编码,效果很好。
这是 VAO 的代码:
// create buffers/arrays
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
// load data into vertex buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
unsigned int sz = sizeof(BoneVertex);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(BoneVertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// set the vertex attribute pointers
// vertex Positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)0);
// vertex normals
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(3 * sizeof(float)));
// vertex texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(6 * sizeof(float)));
// bone weights
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(BoneVertex), (void*)(8 * sizeof(float)));
// bone ids
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glBindVertexArray(0);
BoneVertex 结构:
struct BoneVertex
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 textureCoords;
glm::vec4 boneWeights;
glm::ivec4 boneIDs;
}
这很奇怪,因为前 3 个属性数据似乎没有问题。问题在于 boneIDs 和 boneWeights 这在某种程度上与填充有关,以及数据在结构中的排列方式吗?还是我漏掉了什么?
谢谢
boneIDs
是一个整数数据类型的顶点着色器输入:
layout (location = 4) in ivec4 boneIDs;
如果要为积分属性指定通用顶点属性数据,则必须使用glVertexAttribIPointer
(重点关注I
)而不是glVertexAttribPointer
(参见glVertexAttribPointer
).
请注意,type 参数不指定目标属性的类型,它指定源数据数组的元素类型。 glVertexAttribPointer
将源数据数组转换为浮点值,但 glVertexAttribIPointer
指定整数目标属性的数组。
glVertexAttribPointer(4, 4, GL_INT, GL_FALSE, sizeof(BoneVertex), (void*)(12 * sizeof(float)));
glVertexAttribIPointer(4, 4, GL_INT, sizeof(BoneVertex), (void*)(12 * sizeof(float)));