1. 程式人生 > >OpenGL(七) GeometryInstancing 幾何體例項化

OpenGL(七) GeometryInstancing 幾何體例項化

幾何體例項化( GeometryInstancing ),是一種用於大批量重複物件渲染的GPU技術,以降低客戶端和顯示卡端資料傳輸量,所謂的“一次提交,多次渲染”。簡單說來就是合併DrawCall。

原理

通過

glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0,3);

可以繪製多次幾何體,這樣就可以實現合併。然而不同幾何體都重疊在一起了,這就需要傳入一個差異性引數。然後通過glVertexAttribDivisor來指定分組賦值規則,這就相當於for迴圈最後的++i

實現

首先先設定一個變數陣列,並將它存入VBO中

float posOffsets[] = {
    -1.0f,0.0f,0.0f,
    0.0f,0.0f,0.0f,
    1.0f,0.0f,0.0f
};
GLuint offsetVBO=CreateBufferObject(GL_ARRAY_BUFFER, sizeof(float) * 9, GL_STATIC_DRAW, posOffsets);

//get location index
offsetLocation = glGetAttribLocation(program, "offset");

繪製部分將這組VBO分組:

glBindBuffer(GL_ARRAY_BUFFER, offsetVBO);
glEnableVertexAttribArray(offsetLocation);
glVertexAttribPointer(offsetLocation, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribDivisor(offsetLocation,1);

最後在shader中承接這組資料:

attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;
attribute vec3 offset;

uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 NM;

varying vec3 V_Normal;
varying vec4 V_WorldPos;
varying vec2 V_Texcoord;

void main()
{
    V_Normal=mat3(NM)*normal;
    V_WorldPos=M*vec4(pos,1.0)+vec4(offset,1.0);
    V_Texcoord=texcoord;
    gl_Position=P*V*V_WorldPos;
}

這樣就可以在3個不同的位置繪製相同的物體,且只佔用一次DrawCall。

總結

通過 GeometryInstancing 可以在OpenGL中,實現合併Drawcall。

松陽論道

關注我的微信公眾號,獲取更多優質內容