高级GLSL

来源:互联网 发布:修改表结构的sql语句 编辑:程序博客网 时间:2024/05/21 06:12

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到绑定点0glUniformBlockBinding(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缓冲区绑定到绑定点0glBindBufferRange(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 modelglm::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 modelmodel = 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 modelmodel = 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 modelmodel = glm::translate(model, glm::vec3(60.0, 0, 0));shader3.SetMat4("model", model);shader3.SetVec3("cameraPos", camera.Position);ourmodel.Draw(shader3, textures, cm);

达到了同样的效果: