我有一个像这样初始化的 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];