文中若有代码、术语等错误,欢迎指正
前言
-
此节目的与所作
为了给之前绘制的图形赋予颜色,
由于颜色属于材质的一部分,所以讲了材质系统的设计。
-
如何实际给图形赋予颜色操作
shader里面的fragment片段着色器阶段,设置好uniform
通过c++程序上传材质颜色到这个uniform上,然后将这个颜色赋予给当前的片段。
材质系统
浅谈
-
什么是材质Material
-
一组顶点位置包围了一个区域,需要为这个区域上色,这些颜色就从材质里来。
-
这个材质应该是物体顶点上应有的属性,不包括光源的信息,但是包含对光源如何反应的属性,有反射系数、纹理、光滑度、粗糙度等。
-
-
与纹理Texture的区别
材质(Material)和纹理(Texture)
- 纹理是材质的一部分,就像颜色是材质的一部分
- 纹理是一个图片
- 纹理用来描述物体表面的样子,如木纹
- 材质描述物体表面的细节,包括纹理、光滑度(smoothness), 粗糙度(roughness), 柔软度(softness), 金属质感
- 材质描述物体对光的交互(反射系数、折射系数)性质。
- 材质是一个“东西”,纹理是对某样东西的“感觉”、“视觉”
举例:
当谈到一个模型是木头材质(Material),想到的应该是看上去是木头,表面粗糙、没有金属质感,不太反光;
当谈到一个模型是木头纹理(Texture),代表给它贴了一个木纹理图片。
链接:https://zhuanlan.zhihu.com/p/165588387
抽象API设计
- 材质将Shader作为属性
- 材质读取Shader的相关的uniform,然后通过Set函数上传,并向外提供接口
给图形设置颜色关键代码
-
SandBoxApp
片段着色器部分
std::string blueShaderfragmentSrc = R"( #version 330 core layout(location = 0) out vec4 color; in vec3 v_Position; uniform vec4 u_Color;// 设置颜色uniform void main(){ color = u_Color;// 给当前片段赋予颜色 } )";
cpp代码
// 渲染一组正方形 glm::vec4 redColor(0.8f, 0.2f, 0.3f, 1.0f); glm::vec4 blueColor(0.2f, 0.3f, 0.8f, 1.0f); // 缩放 static glm::mat4 scale = glm::scale(glm::mat4(1.0f), { 0.05f, 0.05f, 0.05f}); for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) { if (j % 2 == 0) { m_BlueShader->UploadUniformFloat4("u_Color", redColor);// 自己写的上传颜色到glsl的接口 } else { m_BlueShader->UploadUniformFloat4("u_Color", blueColor);// 自己写的上传颜色到glsl的接口 } glm::vec3 pos(i * 0.08f, j * 0.08f, 0.0f); glm::mat4 smallsqtransfrom = glm::translate(glm::mat4(1.0f), pos) * scale; Hazel::Renderer::Submit(m_BlueShader, m_SquareVA, smallsqtransfrom); } }
-
Shader.cpp
void Shader::UploadUniformFloat4(const std::string& name, const glm::vec4& values) { GLint location = glGetUniformLocation(m_RendererID, name.c_str()); glUniform4f(location, values.x, values.y, values.z, values.w);// 原始OpenGL代码:上传颜色到glsl的uniform }