GLSL中的内建变量
顶点着色器变量
gl_Position
gl_PointSize 控制点的大小 (需要开启glEnable(GL_PROGRAM_POINT_SIZE))
gl_VertexID 这是一个读取变量,如果当前使用的事glDrawElements进行索引渲染,这个变量存储的是当前绘制顶点的索引,当使用glDrawArrays惊醒渲染时,这个变量存储的是从调用渲染开始到已经处理顶点的数量,也就是意味着知道渲染到了哪个顶点。
片段着色器变量
gl_FragCoord 其z分量存储的是对应片段的深度值,xy分量存储的是片段的屏幕坐标,其原点为窗口的左下角,比如一个1920*1080的屏幕,xy的分量将分别再1920和1080之间。这是个只读变量。
gl_FrontFacing 这个变量是一个bool类型,可以根据这个变量知道当前渲染的片段是属于环绕的正面还是背面。(注意:当开启了面剔除,这个就没有意义了)。
gl_FragDepth 这个变量可以修改片段的深度值。
Unifrom 缓冲对象&Unifrom块布局
由于面对每个shader都要进行频繁的设置相同的uniform变量,所以为了简化,使用缓冲对象和块布局,其道理如下图:
以下是一个使用范例:
///1.这部分是把块和缓冲区都链接到相同的绑定点上
Shader shader("Shader/shader.vs", "Shader/shader.fs");
Shader shader1("Shader/shader.vs", "Shader/shader1.fs");
Shader shader2("Shader/shader.vs", "Shader/shader2.fs");
Shader shader3("Shader/shader.vs", "Shader/shader3.fs");
unsigned int uniform = glGetUniformBlockIndex(shader.ID, "Matrix");
unsigned int uniform1 = glGetUniformBlockIndex(shader1.ID, "Matrix");
unsigned int uniform2 = glGetUniformBlockIndex(shader2.ID, "Matrix");
unsigned int uniform3 = glGetUniformBlockIndex(shader3.ID, "Matrix");
//把uniform块bind到绑定点0
glUniformBlockBinding(shader.ID, uniform, 0);
glUniformBlockBinding(shader1.ID, uniform1, 0);
glUniformBlockBinding(shader2.ID, uniform2, 0);
glUniformBlockBinding(shader3.ID, uniform3, 0);
unsigned int ubo;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//把uniform缓冲区绑定到绑定点0
glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, 2 * sizeof(glm::mat4));
//2.对缓冲区进行数据填充
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)Screen::SCR_WIDTH / (float)Screen::SCR_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = camera.GetViewMatrix();
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//3.使用
shader.use();
// render the loaded model
glm::mat4 model;
model = glm::rotate(model, glm::radians(-90.0f), glm::vec3(1.0f, 0, 0));
model = glm::scale(model, glm::vec3(0.01f, 0.01f, 0.01f)); // it's a bit
shader.SetMat4("model", model);
shader.SetVec3("cameraPos", camera.Position);
ourmodel.Draw(shader, textures,cm);
shader1.use();
// render the loaded model
model = glm::translate(model, glm::vec3(60.0,0,0));
shader1.SetMat4("model", model);
shader1.SetVec3("cameraPos", camera.Position);
ourmodel.Draw(shader1, textures, cm);
shader2.use();
// render the loaded model
model = glm::translate(model, glm::vec3(60.0, 0, 0));
shader2.SetMat4("model", model);
shader2.SetVec3("cameraPos", camera.Position);
ourmodel.Draw(shader2, textures, cm);
shader3.use();
// render the loaded model
model = glm::translate(model, glm::vec3(60.0, 0, 0));
shader3.SetMat4("model", model);
shader3.SetVec3("cameraPos", camera.Position);
ourmodel.Draw(shader3, textures, cm);
达到了同样的效果: