我想在我的OpenGL程序中實現實例化。通過將Model-View-Projection乘法矩陣作爲GLSL程序的輸入,我決定讓GLSL代碼更加高效,以便CPU針對每個實例計算它,而不是GPU。這裏是我的頂點着色器的代碼(大部分是不相關的我的問題):GLSL Instancing - 頂點數據的最大輸入數量?
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 2) in vec3 vertexColor;
layout(location = 3) in vec3 vertexNormal_modelspace;
layout(location = 6) in mat4 models;
layout(location = 10) in mat4 modelsV;
layout(location = 14) in mat4 modelsVP;
// Output data ; will be interpolated for each fragment.
out vec3 newColor;
out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;
uniform mat4 MV;
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
uniform int num_lights;
uniform vec3 Lights[256];
void main(){
// Output position of the vertex, in clip space : MVP * position
gl_Position = P * modelsV * vec4(vertexPosition_modelspace,1);
// Position of the vertex, in worldspace : M * position
Position_worldspace = (models * vec4(vertexPosition_modelspace,1)).xyz;
// Vector that goes from the vertex to the camera, in camera space.
// In camera space, the camera is at the origin (0,0,0).
vec3 vertexPosition_cameraspace = (modelsV * vec4(vertexPosition_modelspace,1)).xyz;
EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;
// Normal of the the vertex, in camera space
Normal_cameraspace = (modelsV * vec4(vertexNormal_modelspace,0)).xyz;
// UV of the vertex. No special space for this one.
newColor = vertexColor;
}
上面的代碼工作,但只是因爲我不使用最後輸入modelsVP計算GL_POSITION。如果我使用它(而不是計算P * modelsV),實例將無法繪製,而我得到這個錯誤:
Linking program
Compiling shader : GLSL/meshColor.vertexshader
Compiling shader : GLSL/meshColor.fragmentshader
Linking program
Vertex info
0(10) : error C5102: input semantic attribute "ATTR" has too big of a numeric index (16)
0(10) : error C5102: input semantic attribute "ATTR" has too big of a numeric index (16)
0(10) : error C5041: cannot locate suitable resource to bind variable "modelsVP". Possibly large array.
我敢肯定,我將它鏈接正確地在我的OpenGL代碼,因爲如果我將輸入位置模型VP與modelsV交換爲10而不是14,我可以使用它,但不能使用modelsV。您可以爲頂點着色器提供最大數量的輸入嗎?我真的想不出任何其他的想法,爲什麼我會得到這個錯誤...
我會包括更多我的OpenGL代碼,這裏是相關的,但我敢肯定,這是正確的不是所有在同一個類或方法):
// Buffer data for VBO. The numbers must match the layout in the GLSL code.
#define position 0
#define uv 1
#define color 2
#define normal 3
#define tangent 4
#define bitangent 5
#define model 6 // 4x4 matrices take 4 positions
#define modelV 10
#define modelVP 14
#define num_buffers 18
GLuint VBO[num_buffers];
glGenBuffers(num_buffers, VBO);
for(int i=0; i<ModelMatrices.size(); i++)
{
mvp.push_back(projection * view * ModelMatrices.at(i));
mv.push_back(view * ModelMatrices.at(i));
}
glBindBuffer(GL_ARRAY_BUFFER, VBO[model]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * ModelMatrices.size(), &ModelMatrices[0], GL_DYNAMIC_DRAW);
for (unsigned int i = 0; i < 4 ; i++) {
glEnableVertexAttribArray(model + i);
glVertexAttribPointer(model + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4),
(const GLvoid*)(sizeof(GLfloat) * i * 4));
glVertexAttribDivisor(model + i, 1);
}
glBindBuffer(GL_ARRAY_BUFFER, VBO[modelV]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * mv.size(), &mv[0], GL_DYNAMIC_DRAW);
for (unsigned int i = 0; i < 4 ; i++) {
glEnableVertexAttribArray(modelV + i);
glVertexAttribPointer(modelV + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4),
(const GLvoid*)(sizeof(GLfloat) * i * 4));
glVertexAttribDivisor(modelV + i, 1);
}
glBindBuffer(GL_ARRAY_BUFFER, VBO[modelVP]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * mvp.size(), &mvp[0], GL_DYNAMIC_DRAW);
for (unsigned int i = 0; i < 4 ; i++) {
glEnableVertexAttribArray(modelVP + i);
glVertexAttribPointer(modelVP + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const GLvoid*)(sizeof(GLfloat) * i * 4));
glVertexAttribDivisor(modelVP + i, 1);
}
世界對相機和相機到透視矩陣*不會更改每個實例。所以他們不需要成爲每個實例的數據。另外,你根本不應該使用任何世界空間。你應該從模型到相機的空間。一個屬性矩陣和一個統一矩陣。 –
世界對照相機矩陣是Model * View,因此每個實例都會改變,因爲它是每次都會改變的Model matrix,不是嗎?而且,我認爲讓CPU計算模型到攝像頭矩陣而不是GPU會更好。 (模型 - 相機空間和世界 - 相機空間是相同的東西,對吧?) – Darius
「*世界對相機矩陣是模型*視圖*」不,這是*模型* - 相機矩陣;世界對相機只是「視圖」。是的,它確實會改變每個實例,但這是我的觀點。您需要*每個實例更改一個*矩陣。它應該是模型到照相機的矩陣,因爲在世界空間工作是一個可怕的想法。 –