我有一个UBO初始化如下:
glGenBuffers(1, &sphereUBO);
glBindBuffer(GL_UNIFORM_BUFFER, sphereUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(SphereUBO) * sphereData.size(), nullptr, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, sphereUBO);
glUniformBlockBinding(rtShader.ID, glGetUniformBlockIndex(shaderProgram, "Spheres"), 0);
rtShader.setInt("u_numSpheres", sphereData.size());
在此之上,我初始化我的球体数据如下:
Scene scene = Scene();
scene.addSphere(glm::vec3(-1.0, 1.0, -1.0), 1.0);
scene.addSphere(glm::vec3(0.0, 1.0, 0.0), 0.1);
scene.addSphere(glm::vec3(5.0, 0.5, 0.0), 0.5);
scene.addSphere(glm::vec3(5.0, 3.5, 0.0), 0.75);
std::vector<SphereUBO> sphereData;
for (int i = 0; i < scene.spheres.size(); i++) {
SphereUBO sphere;
sphere.position = scene.spheres[i].position;
sphere.radius = scene.spheres[i].radius;
sphere.albedo = glm::vec3(scene.spheres[i].material.albedo[0], scene.spheres[i].material.albedo[1], scene.spheres[i].material.albedo[2]);
sphereData.push_back(sphere);
}
我已经打印出sphereData以确保数据正确传递。最后,我更新了缓冲区的内容:
glBindBuffer(GL_UNIFORM_BUFFER, sphereUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(SphereUBO) * sphereData.size(), sphereData.data());
但是,我只看到一个渲染的球体!我已经确认了所有的球体都在渲染,但它们在某种程度上都是一样的。我在我的片段着色器中有这个函数:
bool raycast(Ray ray, out HitPoint hitPoint) {
bool hit = false;
float minHitDistance = 10000;
float hitDistance;
for (int i = 0; i < u_numSpheres; i++) {
if (sphereIntersection(u_spheres[i].position, u_spheres[i].radius, ray, hitDistance)) {
hit = true;
if (hitDistance < minHitDistance) {
minHitDistance = hitDistance;
hitPoint.position = ray.origin + ray.direction * minHitDistance;
hitPoint.normal = normalize(hitPoint.position - u_spheres[i].position);
hitPoint.material = Material(u_spheres[i].albedo);
}
}
}
return hit;
}
我知道它们都是一样的,因为当我不做for循环,只检查第一个或第二个球体时,它们的渲染结果是一样的。
我有我的缓冲/制服声明在这里:
uniform int u_numSpheres;
layout(std140) uniform Sphere{
vec3 position;
float radius;
vec3 albedo;
} u_spheres[32];
1条答案
按热度按时间kulphzqa1#
首先是typo:“Spheres”不是一个有效的统一块名,所以这几乎肯定会返回
GL_INVALID_INDEX
,这将导致对glUniformBlockBinding
的调用失败。但更重要的是,即使你把它命名为“球体”,以符合你的UBO定义...仍然没有统一的块命名为“球体”。但是,有一个统一的块名为
Sphere[0]
。还有一个叫Sphere[1]
。诸如此类。你看,问题是你认为
Sphere
是一个统一的块。它不是。它是一个数组 * 的统一块 *,而不是一个统一块 * 包含 * 一个数组。这就是将接口块声明为数组的意思。你有32个统一块(这真的应该会导致编译错误)。您真正需要的是声明一个名为
Sphere
的struct
,然后有一个包含此类类型数组的统一块。stop usingvec3
。