From df10fe28da162fa8518e35953420bfbd7c42fee5 Mon Sep 17 00:00:00 2001 From: wuweizhou Date: Tue, 23 Jun 2015 17:18:54 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01 Getting started/05 Shaders.md | 99 ++++++++++++++++++++++++++++++- 01 Getting started/pic1.jpg | Bin 0 -> 48619 bytes 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 01 Getting started/pic1.jpg diff --git a/01 Getting started/05 Shaders.md b/01 Getting started/05 Shaders.md index 2ff0c4d..a3fc661 100644 --- a/01 Getting started/05 Shaders.md +++ b/01 Getting started/05 Shaders.md @@ -1,6 +1,99 @@ 本文作者JoeyDeVries,由codeman001翻译自[http://learnopengl.com](http://learnopengl.com/#!Getting-started/Shaders) -##Shaders +##着色器 -未翻译完成... ---- +在[Hello Triangle](https://github.com/Geequlim/LearnOpenGL-CN/blob/master/01%20Getting%20started/04%20Hello%20Triangle.md) 中已经提到,着色器是在GPU上运行的小程序,这些程序负责处理图形渲染管线的特定阶段,简单来说,着色器也是一个处理输入输出的程序。着色器是非常孤立执行的程序,彼此之间没有太多的交互, + +在前面的教程中,我们大致介绍了表面着色器和如何正确使用它们。接下来我们讲接触更加流行的OpenGL着色语言 + +###GLSL +GLSL是写法类似C语言,GLSL是专门针对图形以及向量和矩阵变化设计的。着色器通常开始生命一个版本信息,然后是输入、输出列表以及常量和入口函数(main函数),每个着色器都是在入口函数处来处理输入参数。然后输出结果。 + + +着色器通常具有以下结构: + + #version version_number + in type in_variable_name; + in type in_variable_name; + 6.2 Types 52 + out type out_variable_name; + uniform type uniform_name; + int main() + { + // Process input(s) and do some weird graphics stuff + ... + // Output processed stuff to output variable + out_variable_name = weird_stuff_we_processed; + } + +所谓的顶点着色器就讲顶点属性作为输入的着色器,顶点属性的个数主要受限于硬件实现,OpenGL的保证总有至少16个四分量的顶点可以使用,但是硬件可能个多些,可以通过查询:**GL_MAX_VERTEX_ATTRIBS** + + GLint nrAttributes; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); + std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl; + +这个结果最小返回16,一般情况下使用。 + +###类型 + + +GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基础类型比如:int,float, double, uint and bool等,还用两种我们在教程中经常用到的容器类型:vectors(向量) 和 matrices(矩阵),稍后会提到。 + + +####向量 +一个向量可以包含1-4个分量,分量的类型可以是上面我们提到的基础类型。向量个类型名字规则如下: + +- vecn: 默认向量,有个n浮点型分量. +- bvecn: 有n个bool分量. +- ivecn: 有n个整型分量. +- uvecn: 有n个无符号整型分量. +- dvecn: 有n个双浮点型分量. + +大多数情况下我们使用vecn,因为浮点型足够满足我们大多数需求。 +向量的分量可以通过vec.x来访问第一个分量,同时可以使用.x,.y,.z,.w来访问一个向量的四个成员,同样可以使用rgba来访问颜色值对应的向量,纹理坐标则可以使用stpq来访问分量的值。 +向量的访问方式支持趣味性和扩展性,被称为交叉混合性,实例如下: + + vec2 someVec; + vec4 differentVec = someVec.xyxx; + vec3 anotherVec = differentVec.zyw; + vec4 otherVec = someVec.xxxx + anotherVec.yxzy; +可以使用任意组合来组成新向量,同时也可以把维度小的向量放在高纬度向量的构造函数里来构成新的向量。如下代码: + + vec2 vect = vec2(0.5f, 0.7f); + vec4 result = vec4(vect, 0.0f, 0.0f); + vec4 otherResult = vec4(result.xyz, 1.0f); + +###输入和输出 +着色器是运行在GPU上的小程序,但是麻雀虽小五脏俱全,也会有输入和输出来构成完整的程序,GLSL使用in和out关键字来定义输入和输出。每个着色器可以是这些关键字来指定输入和输出,输入变量经过处理以后会得到适合下个处理阶段可以使用的输出变量,顶点着色器和片段着色器有点小却别。 + +顶点着色器接受特定格式的输入,否则不能正确使用。顶点着色器直接接受输入的顶点数据,但是需要在CPU一边指定数据的对应的位置,前面的教程可以到对位置0的输入(location=0),所以顶点着色器需要一个特定的声明来确定CPU和GPU数据对应关联关系, + + 也可以使用*glGetAttribLocation*来查询对应的位置,这样可以省略layout的声明,但是我觉得可以是用layout声明比较好,这也可以减少GPU的一些工作 +对于片段着色器有个vec4的颜色作为特定的输出,因为片段处理后最终是要生产一个颜色来显示的。否则将输出黑色或白色颜色作为输出。 + +如果我们想从一个着色器向另外一个发送数据,我们需要在发送方定义一个输出,然后再接收方顶一个输入,同时保证这两个变量类型和名字是相同的。 +下面是一个实例来展示如何从顶点着色器传递一个颜色值跟片段着色器使用: + +***顶点着色器*** + + #version 330 core + layout (location = 0) in vec3 position; // The position variable has attribute position 0 + out vec4 vertexColor; // Specify a color output to the fragment shader + void main() + { + gl_Position = vec4(position, 1.0); + vertexColor = vec4(0.5f, 0.0f, 0.0f, 1.0f); + } + +***片段着色器*** + + #version 330 core + in vec4 vertexColor; // 从顶点着色器获得输入 (名字和类型都是一样的) + out vec4 color; + void main() + { + color = vertexColor; + } + +可以看到在顶点着色器生命了一个向量:*vertexColor* 有out修饰,同时在片段着色器声明了一个*vertexColor* 使用in来修饰,这样片段着色器就可以获取顶点着色器处理的*vertexColor*的结果了。 +根据上面shader,可以得出下图的效果: \ No newline at end of file diff --git a/01 Getting started/pic1.jpg b/01 Getting started/pic1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3386c147d785401cef0abebb6d6784eef8e36477 GIT binary patch literal 48619 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 -N7^a`eTI7UXpvy+n1RL`OC>AHMW{+`jr-i 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 Qg&fc3!rvL|GoruvAI|J1VE_OC literal 0 HcmV?d00001 From 0f9ab0b74754968cde263a421213c739987a997d Mon Sep 17 00:00:00 2001 From: wuweizhou Date: Tue, 23 Jun 2015 19:17:14 +0800 Subject: [PATCH 2/4] =?UTF-8?q?-=E6=9B=B4=E6=96=B0=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01 Getting started/05 Shaders.md | 67 ++++++++++++++++++++++++++++++- 01 Getting started/pic2.jpg | Bin 0 -> 72034 bytes 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 01 Getting started/pic2.jpg diff --git a/01 Getting started/05 Shaders.md b/01 Getting started/05 Shaders.md index a3fc661..8f10088 100644 --- a/01 Getting started/05 Shaders.md +++ b/01 Getting started/05 Shaders.md @@ -96,4 +96,69 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基 } 可以看到在顶点着色器生命了一个向量:*vertexColor* 有out修饰,同时在片段着色器声明了一个*vertexColor* 使用in来修饰,这样片段着色器就可以获取顶点着色器处理的*vertexColor*的结果了。 -根据上面shader,可以得出下图的效果: \ No newline at end of file +根据上面shader,可以得出下图的效果: + +![shader效果](https://github.com/codeman001/LearnOpenGL-CN/blob/master/01%20Getting%20started/pic1.jpg?raw=true) + + +**常量** +常量是另外一个中从CPU端向GPU传输数据的方式,常量方式跟顶点数据有非常明显的不同。常量有两个特性: + +1.具有全局性,可以在着色器不同阶段来获取同一个常量 + +2.不变性,一旦设置了值,在渲染过程中就不能被改变,只有从新设置才能改变。 + +声明常量非常简单使用uniform 放在类型和变量名前面即可。下面看一个例子: + + #version 330 core + out vec4 color; + uniform vec4 ourColor; // + code. + void main() + { + color = ourColor; + } +声明了一个ourColor为常量类型,然后把它的值付给了输出变量color。 + + 注意:如果声明了一个从来没用到常量,GLSL的编译器会默认删除这个常量,由此可能导致一些莫名的问题。 +现在这个常量还是个空值,接下来给ourColor在CPU端传递数据给它。思路:获取ourColor在索引位置,然后传递数据给这个位置。另外做一些小动作,不传递固定的这个,传递一个随时间变化的值,如下: + + GLfloat timeValue = glfwGetTime(); + GLfloat greenValue = (sin(timeValue) / 2) + 0.5; + GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor"); + glUseProgram(shaderProgram); + glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); + +首先通过glfwGetTime函数获取程序运行时间(秒数)。然后使用sin函数将greenValue的值控制在0-1。 + +然后使用glGetUniformLocation函数查询ourColor的索引位置。是一个参数是要查询的着色器程序,第二个参数是常量在着色器中声明的变量名。如果glGetUniformLocation函数返回-1,表明没找到对应的常量的索引位置。 + +最合使用glUniform4f来完成赋值。 + +注意:使用glGetUniformLocation 不需要在glUseProgram之后,但是glUniform4f一定要在lUseProgram之后,因为我们也只能对当前激活的着色器程序传递数据。 +到目前为止已经学会了这么给常量传递数据和渲染使用这些数据,如果我们想每帧改变常量的值,我们需要在主循环的不停的计算和更新常量的值。 + + while(!glfwWindowShouldClose(window)) + { + // Check and call events + glfwPollEvents(); + // Render + // Clear the colorbuffer + glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + // Be sure to activate the shader + glUseProgram(shaderProgram); + // Update the uniform color + GLfloat timeValue = glfwGetTime(); + GLfloat greenValue = (sin(timeValue) / 2) + 0.5; + GLint vertexColorLocation = glGetUniformLocation( + shaderProgram, "ourColor"); + glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f,1.0f); + // Now draw the triangle + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); + } + +如果运行正常的话我们能看到一个绿色到黑色,黑色到绿色变化的三角形, +可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated) diff --git a/01 Getting started/pic2.jpg b/01 Getting started/pic2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2f31bee2d9e639803fe4b810d2a4eec98bb69e6f GIT binary patch literal 72034 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 FzW_5$v>*Tg literal 0 HcmV?d00001 From 8872b252eace0887cbb5edc133b9d22d527ed81c Mon Sep 17 00:00:00 2001 From: wuweizhou Date: Tue, 23 Jun 2015 19:56:27 +0800 Subject: [PATCH 3/4] =?UTF-8?q?-=E7=AC=AC=E4=B8=80=E7=89=88=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01 Getting started/05 Shaders.md | 136 +++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/01 Getting started/05 Shaders.md b/01 Getting started/05 Shaders.md index 8f10088..51906f8 100644 --- a/01 Getting started/05 Shaders.md +++ b/01 Getting started/05 Shaders.md @@ -162,3 +162,139 @@ GLSL跟一般的编程语言一样,定义了一些常用的数据类型,基 如果运行正常的话我们能看到一个绿色到黑色,黑色到绿色变化的三角形, 可以查看完整的代码[实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-interpolated) + + +**着色器程序管理程序** + +编写、编译和管理着色器程序是非常繁重的工作,为了减轻这个工作量我们自己定义一个着色器程序管理器,负责读取着色器程序文件,然后编译他们,链接并检查着色器程序有无错误发生。这也可以让我们把已经学到的知识封装到抽象的对象里。 + +我们首先顶一个着色器程序的头文件,如下: + + #ifndef SHADER_H + #define SHADER_H + #include + #include + #include + #include + using namespace std; + #include ; // Include glew to get all the required + OpenGL headers + class Shader + { + public: + // The program ID + GLuint Program; + // Constructor reads and builds the shader + Shader(const GLchar* vertexSourcePath, const GLchar*fragmentSourcePath); + // Use the program + void Use(); + }; + #endif + +着色器程序类包含一个着色器程序ID,有一个接受顶点和片段程序的接口,这个两个路径就是普通的文本文件就可以了。 +Use函数是一个工具属性的函数,主要是控制当前着色器程序是否激活。 + +读取着色器程序文件 + + Shader(const GLchar* vertexPath, const GLchar* fragmentPath) + { + // 1. Retrieve the vertex/fragment source code from + filePath + std::string vertexCode; + std::string fragmentCode; + try + { + // Open files + std::ifstream vShaderFile(vertexPath); + std::ifstream fShaderFile(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + // Read file’s buffer contents into streams + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + // close file handlers + vShaderFile.close(); + fShaderFile.close(); + // Convert stream into GLchar array + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + } + catch(std::exception e) + { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << + std::endl; + } + + +接下来编译和链接这些程序,同时收集一些编译和链接的错误,来帮助我们调试。 + + // 2. Compile shaders + GLuint vertex, fragment; + GLint success; + GLchar infoLog[512]; + // Vertex Shader + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + // Print compile errors if any + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if(!success) + { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" + << infoLog << std::endl; + }; + // Similiar for Fragment Shader + [...] + // Shader Program + this->Program = glCreateProgram(); + glAttachShader(this->Program, vertex); + glAttachShader(this->Program, fragment); + glLinkProgram(this->Program); + // Print linking errors if any + glGetProgramiv(this->Program, GL_LINK_STATUS, &success); + if(!success) + { + glGetProgramInfoLog(this->Program, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << + infoLog << std::endl; + } + // Delete the shaders as they’re linked into our program now + and no longer necessery + glDeleteShader(vertex); + glDeleteShader(fragment); + +最后来实现一个use函数 + + void Use() { glUseProgram(this->Program); } +接下来是一个使用这个简单实例: + + Shader ourShader("path/to/shaders/shader.vs", "path/to/shaders/shader.frag"); + ... + while(...) + { + ourShader.Use(); + glUniform1f(glGetUniformLocation(ourShader.Program, " + someUniform"), 1.0f); + DrawStuff(); + } +上面我们已经把顶点着色器和片段着色器代码分别放在shader.vs和shader.frag里面了,这些文件的名字和后缀名都可以随意命名的,只要符合文件名规范就好。 +完整的代码实例: + +[使用的实例](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-using-object) + +[着色器类](http://learnopengl.com/code_viewer.php?type=header&code=shader) + +[顶点着色器代码](http://learnopengl.com/code_viewer.php?type=vertex&code=getting-started/basic) + +[片段着色器代码](http://learnopengl.com/code_viewer.php?type=fragment&code=getting-started/basic) + + +**练习题** + +1.通过调整的顶点着色器,以使三角形是倒置 [答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise1) + +2.通过一个常量,使得三角在x方向偏移 [答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise2) + +3.使用in 和out 关键字,把顶点着色器的位置数据作为片段着色器的颜色,然后看看得出的三角形颜色,进一步理解差值的问题,同时可以尝试回答下面的问题:为什么我们三角形左下侧有黑边?:[答案](http://learnopengl.com/code_viewer.php?code=getting-started/shaders-exercise3) + + From 020704b25876118f89959d03995d1d7b721782e0 Mon Sep 17 00:00:00 2001 From: wuweizhou Date: Tue, 23 Jun 2015 19:59:35 +0800 Subject: [PATCH 4/4] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01 Getting started/05 Shaders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/01 Getting started/05 Shaders.md b/01 Getting started/05 Shaders.md index 51906f8..639ca3e 100644 --- a/01 Getting started/05 Shaders.md +++ b/01 Getting started/05 Shaders.md @@ -1,4 +1,4 @@ -本文作者JoeyDeVries,由codeman001翻译自[http://learnopengl.com](http://learnopengl.com/#!Getting-started/Shaders) +本文作者JoeyDeVries,由[codeman001](https://github.com/codeman001)翻译自[http://learnopengl.com](http://learnopengl.com/#!Getting-started/Shaders) ##着色器