我想通过一次绘制调用渲染100,000多个立方体(由36个顶点构成,在同一个VAO中使用索引几何体),这可能吗?
所有几何数据(顶点数据)都是相同的,因为它们都是立方体。投影和摄像机视图也相同,并作为制服传递到顶点着色器。
Render.cpp
for (auto chunk : world->chunks) {
for (auto cube : chunk.blocks) {
glBindTexture(GL_TEXTURE_CUBE_MAP, textures[cube.texture]);
// Model - transform_z * transform_y * transform_x * transform_translation * transform_scaling
model = Mat4<GLfloat>();
model = model.translate(cube.position);
model = model.scale(cube.scale);
model = model * transformation_matrix_x(cube.theta_x);
model = model * transformation_matrix_y(cube.theta_y);
model = model * transformation_matrix_z(cube.theta_z);
glUniformMatrix4fv(gl_model, 1, GL_TRUE, model.data());
// One draw call per cube is not scalable
glDrawElements(GL_TRIANGLES, cube.indices.size(), GL_UNSIGNED_INT, 0);
}
// A draw call like this would be nice since they share so much data.
// glDrawLotsOfElements(GL_TRIANGLES, cube.indices.size() * numCubes, GL_UNSIGNED_INT, 0);
}
顶点着色器
#version 330 core
in vec3 position;
in vec4 vColor;
out vec4 fColor;
out vec3 fTexcoord;
// Model
uniform mat4 model;
// View or a.k.a camera matrix
uniform mat4 camera_view;
// Projection
uniform mat4 projection;
void main() {
gl_Position = projection * camera_view * model * vec4(position, 1.0f);
fColor = vColor;
fTexcoord = normalize(position);
}
如果重要的话,立方体的数量是动态的。
答案 0 :(得分:0)
我在渲染粒子时使用过实例渲染,所以我们会看看这是否能指向正确的方向。
在游戏循环之前,您将调用渲染场景的功能。在该功能中,您可以像这样设置模型矩阵,这样您就可以将每个立方体放在世界的不同位置:
# Save Compressed Images
IMAGES=`grep '^\s*image' docker-compose.yml | sed 's/image://' | sort | uniq`
docker save $IMAGES | gzip > images.tar.gz
# Load Compressed Images
gunzip -c images.tar.gz | docker load
然后,您将进入一个循环,您将为每个立方体赋予不同的位置
//matrices for the cubes
//set amount by the number of cubes you want to draw
glm::mat4* modelMatrices;
modelMatrices = new glm::mat4[amount];
现在填充缓冲区时看起来有点不同,因为你必须将模型矩阵(mat4)作为属性发送到GPU端,所以你需要4个顶点属性指针,而且不要忘了
for (GLuint i = 0; i < amount; i++)
{ //use a function like rand() to get the x,y,z values different
glm::mat4 model;
model = glm::translate(model, glm::vec3(x, y, z));
modelMatrices[i] = model;
}
最后
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
然后,当您实际渲染多维数据集时,您将不得不再次使用glDrawArraysInstanced(GL_POINTS, 0, 1, amount); //replace to specify for a cube
。
在GPU方面,您只需要使用之前发送的模型矩阵替换通常的模型矩阵。