当前位置: 首页 > news >正文

做英语题目的网站广告设计公司报价单

做英语题目的网站,广告设计公司报价单,滑县网站建设哪家专业,广告设计公司市场专员LearnOpenGL - Shaders 一、说明 着色器是openGL渲染的重要内容#xff0c;客户如果想自我实现渲染灵活性#xff0c;可以用着色器进行编程#xff0c;这种程序小脚本被传送到GPU的显卡内部#xff0c;起到动态灵活的着色作用。 二、着色器简述 正如“Hello Triangle”一章… LearnOpenGL - Shaders 一、说明         着色器是openGL渲染的重要内容客户如果想自我实现渲染灵活性可以用着色器进行编程这种程序小脚本被传送到GPU的显卡内部起到动态灵活的着色作用。 二、着色器简述         正如“Hello Triangle”一章中提到的着色器是驻留在 GPU 上的小程序。这些程序针对图形管道的每个特定部分运行。从基本意义上讲着色器只不过是将输入转换为输出的程序。着色器也是非常孤立的程序因为它们不允许相互通信他们唯一的沟通方式是通过输入和输出。         在上一章中我们简要介绍了着色器的表面以及如何正确使用它们。现在我们将以更通用的方式解释着色器特别是 OpenGL 着色语言。 三、着色器语言GLSL         着色器是用类 C 语言 GLSL 编写的。 GLSL 专为图形使用而定制包含专门针对矢量和矩阵操作的有用功能。         着色器总是以版本声明开始后面是输入和输出变量、制服及其相关的列表。主要的功能。每个着色器的入口点位于其主要的函数我们处理任何输入变量并将结果输出到其输出变量中。如果您不知道什么是uniform请不要担心我们很快就会介绍。 3.1 GLSL简述         着色器通常具有以下结构 #version version_number in type in_variable_name; in type in_variable_name;out type out_variable_name;uniform type uniform_name;void main() {// process input(s) and do some weird graphics stuff...// output processed stuff to output variableout_variable_name weird_stuff_we_processed; }当我们具体讨论顶点着色器时每个输入变量也称为顶点属性。我们可以声明的顶点属性的最大数量受到硬件的限制。 OpenGL 保证始终有至少 16 个 4 分量顶点属性可用但某些硬件可能允许更多您可以通过查询GL_MAX_VERTEX_ATTRIBS来检索 int nrAttributes; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, nrAttributes); std::cout Maximum nr of vertex attributes supported: nrAttributes std::endl;这通常会返回最小值16对于大多数目的来说应该足够了。 3.2 数据类型- 向量         与任何其他编程语言一样GLSL 具有用于指定我们要使用的变量类型的数据类型。 GLSL 拥有我们从 C: int、float、double和uint等语言中了解到的大多数默认基本类型 bool。 GLSL 还具有我们将经常使用的两种容器类型即vectors和matrices。我们将在后面的章节中讨论矩阵。         GLSL 中的向量是用于刚才提到的任何基本类型的 2,3 或 4 个分量容器。它们可以采用以下形式n代表组件的数量 vecn默认的浮点数向量n。bvecn布尔向量n。ivecn整数向量n。uvecn无符号整数向量n。dvecn双分量向量n。         大多数时候我们会使用基本的vecn因为浮动足以满足我们的大多数目的。   vec.x可以通过向量的x第一个分量 来访问向量的分量。您可以使用.x、.y、.z和.w分别访问它们的第一个、第二个、第三个和第四个组件。 GLSL 还允许您使用rgba颜色或stpq纹理坐标访问相同的组件。         矢量数据类型允许进行一些有趣且灵活的组件选择称为搅动。 Swizzling 允许我们使用如下语法 vec2 someVec; vec4 differentVec someVec.xyxx; vec3 anotherVec differentVec.zyw; vec4 otherVec someVec.xxxx anotherVec.yxzy;您可以使用最多 4 个字母的任意组合来创建新向量相同类型只要原始向量具有这些组件即可例如不允许访问.za 的组件。vec2我们还可以将向量作为参数传递给不同的向量构造函数调用从而减少所需参数的数量 vec2 vect vec2(0.5, 0.7); vec4 result vec4(vect, 0.0, 0.0); vec4 otherResult vec4(result.xyz, 1.0);因此向量是一种灵活的数据类型我们可以将其用于各种输入和输出。在整本书中您将看到大量关于如何创造性地管理向量的示例。 3.2 来龙去脉         着色器本身就是很好的小程序但它们是整体的一部分因此我们希望在各个着色器上有输入和输出以便我们可以移动东西。 GLSL 专门为此目的定义了in和关键字。out每个着色器都可以使用这些关键字指定输入和输出并且只要输出变量与它们传递的下一个着色器阶段的输入变量匹配即可。不过顶点着色器和片段着色器略有不同。         顶点着色器应该接收某种形式的输入否则它将非常低效。顶点着色器的输入有所不同因为它直接从顶点数据接收输入。为了定义顶点数据的组织方式我们使用位置元数据指定输入变量以便我们可以在 CPU 上配置顶点​​属性。我们在前一章中已经看到了这一点layout (location 0)。因此顶点着色器需要为其输入提供额外的布局规范以便我们可以将其与顶点数据链接起来。         也可以省略layout (location 0)说明符并通过以下方式查询 OpenGL 代码中的属性位置glGetAttribLocation但我更愿意将它们设置在顶点着色器中。它更容易理解并为您和 OpenGL节省一些工作。 另一个例外是片段着色器需要vec4颜色输出变量因为片段着色器需要生成最终的输出颜色。如果您未能在片段着色器中指定输出颜色这些片段的颜色缓冲区输出将是未定义的这通常意味着 OpenGL 会将它们渲染为黑色或白色。 因此如果我们想要将数据从一个着色器发送到另一个着色器我们必须在发送着色器中声明一个输出并在接收着色器中声明一个类似的输入。当两侧的类型和名称相同时OpenGL 会将这些变量链接在一起然后就可以在着色器之间发送数据这是在链接程序对象时完成的。为了向您展示这在实践中是如何工作的我们将更改上一章中的着色器让顶点着色器决定片段着色器的颜色。 2.2.1 顶点着色器 #version 330 core layout (location 0) in vec3 aPos; // the position variable has attribute position 0out vec4 vertexColor; // specify a color output to the fragment shadervoid main() {gl_Position vec4(aPos, 1.0); // see how we directly give a vec3 to vec4s constructorvertexColor vec4(0.5, 0.0, 0.0, 1.0); // set the output variable to a dark-red color }3.2.2 片段着色器 #version 330 core out vec4 FragColor;in vec4 vertexColor; // the input variable from the vertex shader (same name and same type) void main() {FragColor vertexColor; } 您可以看到我们声明了一个vertexColor变量作为vec4我们在顶点着色器中设置的输出并且我们在片段着色器中声明了一个类似的vertexColor输入。由于它们具有相同的类型和名称因此片段着色器中的vertexColor链接到顶点着色器中的vertexColor。因为我们在顶点着色器中将颜色设置为深红色所以生成的片段也应该是深红色。下图显示了输出         我们开始吧我们刚刚设法将一个值从顶点着色器发送到片段着色器。让我们稍微调味一下看看我们是否可以将颜色从我们的应用程序发送到片段着色器 3.4 uniform         制服是将数据从 CPU 上的应用程序传递到 GPU 上的着色器的另一种方法。然而制服与顶点属性相比略有不同。首先制服是全球的。全局意味着统一变量对于每个着色器程序对象都是唯一的并且可以在着色器程序中的任何阶段从任何着色器访问。其次无论您将统一值设置为多少统一都会保留其值直到重置或更新为止。         要在 GLSL 中声明统一我们只需将uniform关键字添加到具有类型和名称的着色器即可。从那时起我们可以在着色器中使用新声明的制服。让我们看看这次我们是否可以通过统一设置三角形的颜色 #version 330 core out vec4 FragColor;uniform vec4 ourColor; // we set this variable in the OpenGL code.void main() {FragColor ourColor; } 我们在片段着色器中声明了一个统一的vec4 ourColor并将片段的输出颜色设置为该统一值的内容。由于制服是全局变量我们可以在任何我们想要的着色器阶段定义它们因此不需要再次通过顶点着色器来获取片段着色器的内容。我们不在顶点着色器中使用此统一因此无需在那里定义它。         如果您声明的统一变量未在 GLSL 代码中的任何地方使用编译器会默默地从编译版本中删除该变量这会导致一些令人沮丧的错误记住这一点         制服目前是空的我们还没有向制服添加任何数据所以让我们尝试一下。我们首先需要在着色器中找到统一属性的索引/位置。一旦我们有了制服的索引/位置我们就可以更新它的值。我们不要将单一颜色传递给片段着色器而是通过随着时间的推移逐渐改变颜色来增加趣味性 float timeValue glfwGetTime(); float greenValue (sin(timeValue) / 2.0f) 0.5f; int vertexColorLocation glGetUniformLocation(shaderProgram, ourColor); glUseProgram(shaderProgram); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);首先我们通过以下方式检索运行时间以秒为单位glfw获取时间()。然后我们在0.0-范围内改变1.0颜色罪函数并将结果存储在greenValue中。         然后我们使用以下命令查询ourColor制服 的位置glGetUniformLocation。我们向查询函数提供着色器程序和制服名称我们要从中检索位置。如果glGetUniformLocation返回后-1找不到位置。最后我们可以使用以下命令设置统一值统一4f功能。请注意查找统一位置并不要求您首先使用着色器程序但更新统一确实需要您首先使用该程序通过调用glUse程序因为它在当前活动的着色器程序上设置统一。         因为 OpenGL 的核心是一个 C 库所以它没有对函数重载的本机支持因此只要可以使用不同类型调用函数OpenGL 就会为所需的每种类型定义新函数统一就是一个完美的例子。该函数需要您要设置的制服类型的特定后缀。一些可能的后缀是 f该函数期望 afloat作为其值。i该函数需要 anint作为其值。ui该函数需要 anunsigned int作为其值。3f该函数期望 3 floats 作为其值。fv该函数需要一个float向量/数组作为其值。         每当您想要配置 OpenGL 的选项时只需选择与您的类型相对应的重载函数即可。在我们的例子中我们想要单独设置 4 个制服浮点数因此我们通过以下方式传递数据统一4f请注意我们也可以使用该fv版本。         现在我们知道如何设置统一变量的值我们可以使用它们进行渲染。如果我们希望颜色逐渐变化我们希望每一帧都更新这个制服否则如果我们只设置一次三角形将保持单一的纯色。因此我们计算greenValue并更新每次渲染迭代的统一值 while(!glfwWindowShouldClose(window)) {// inputprocessInput(window);// render// clear the colorbufferglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// be sure to activate the shaderglUseProgram(shaderProgram);// update the uniform colorfloat timeValue glfwGetTime();float greenValue sin(timeValue) / 2.0f 0.5f;int vertexColorLocation glGetUniformLocation(shaderProgram, ourColor);glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);// now render the triangleglBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);// swap buffers and poll IO eventsglfwSwapBuffers(window);glfwPollEvents(); }该代码是对先前代码的相对简单的改编。这次我们在绘制三角形之前每帧更新一个统一值。如果正确更新制服您应该会看到三角形的颜色逐渐从绿色变为黑色然后又变回绿色。         如果您遇到困难 请查看此处的 源代码。         正如您所看到的制服是一个有用的工具用于设置可能更改每帧的属性或者用于在应用程序和着色器之间交换数据但是如果我们想为每个顶点设置颜色怎么办在这种情况下我们必须声明与顶点一样多的制服。更好的解决方案是在顶点属性中包含更多数据这就是我们现在要做的。 3.5 更多属性         我们在上一章中看到了如何填充 VBO、配置顶点属性指针并将其全部存储在 VAO 中。这次我们还想将颜色数据添加到顶点数据中。我们将把颜色数据作为 3float秒添加到顶点数组中。我们分别为三角形的每个角指定红色、绿色和蓝色 float vertices[] {// positions // colors0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top }; 由于我们现在有更多数据要发送到顶点着色器因此有必要调整顶点着色器以也接收我们的颜色值作为顶点属性输入。请注意我们使用布局说明符 将aColor属性的位置设置为 1 #version 330 core layout (location 0) in vec3 aPos; // the position variable has attribute position 0 layout (location 1) in vec3 aColor; // the color variable has attribute position 1out vec3 ourColor; // output a color to the fragment shadervoid main() {gl_Position vec4(aPos, 1.0);ourColor aColor; // set ourColor to the input color we got from the vertex data } 由于我们不再使用统一的片段颜色但现在使用ourColor输出变量我们还必须更改片段着色器 #version 330 core out vec4 FragColor; in vec3 ourColor;void main() {FragColor vec4(ourColor, 1.0); }因为我们添加了另一个顶点属性并更新了 VBO 的内存所以我们必须重新配置顶点属性指针。 VBO 内存中的更新数据现在看起来有点像这样         知道当前布局我们可以更新顶点格式glVertexAttribPointer: // position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float))); glEnableVertexAttribArray(1);的前几个论点glVertexAttribPointer都比较简单。这次我们在属性 location 上配置顶点​​属性1。颜色值的大小为3 floats我们不对这些值进行标准化。         由于我们现在有两个顶点属性我们必须重新计算步幅值。为了获得x数据数组中的下一个属性值例如位置向量的下一个分量我们必须将6 floats 向右移动三个用于位置值三个用于颜色值。这给我们提供了 a 大小的 6 倍float以字节为单位的步幅值 ( 24bytes)。 另外这次我们必须指定一个偏移量。对于每个顶点位置顶点属性是第一个因此我们声明偏移量0。颜色属性在位置数据之后开始因此偏移量以3 * sizeof(float)字节 ( 12bytes) 为单位。         运行应用程序应该会产生以下图像         如果您遇到困难 请查看此处的 源代码。         该图像可能并不完全符合您的预期因为我们只提供了 3 种颜色而不是我们现在看到的巨大调色板。这都是某种叫做的东西的结果片段插值在片段着色器中。渲染三角形时光栅化阶段通常会产生比最初指定的顶点多得多的片段。然后光栅化器根据这些片段在三角形上的位置来确定每个片段的位置。         基于这些立场插值所有片段着色器的输入变量。举例来说我们有一条线其上部点为绿色下部点为蓝色。如果片段着色器在位于该线位置周围的片段上运行70%则其生成的颜色输入属性将是绿色和蓝色的线性组合更准确地说30%蓝色和70%绿色。         这正是三角区发生的情况。我们有 3 个顶点因此有 3 种颜色从三角形的像素来看它可能包含大约 50000 个片段片段着色器在这些像素之间插入颜色。如果你仔细观察颜色你会发现这一切都是有道理的红色到蓝色首先变成紫色然后变成蓝色。片段插值应用于片段着色器的所有输入属性。 四、建立我们自己的着色器类         编写、编译和管理着色器可能相当麻烦。作为着色器主题的最后一步我们将通过构建一个着色器类来让我们的生活变得更轻松一些该类从磁盘读取着色器、编译和链接它们、检查错误并且易于使用。这也让您了解如何将迄今为止学到的一些知识封装到有用的抽象对象中。         我们将完全在头文件中创建着色器类主要是出于学习目的和可移植性。让我们首先添加所需的包含并定义类结构 #ifndef SHADER_H #define SHADER_H#include glad/glad.h // include glad to get all the required OpenGL headers#include string #include fstream #include sstream #include iostreamclass Shader { public:// the program IDunsigned int ID;// constructor reads and builds the shaderShader(const char* vertexPath, const char* fragmentPath);// use/activate the shadervoid use();// utility uniform functionsvoid setBool(const std::string name, bool value) const; void setInt(const std::string name, int value) const; void setFloat(const std::string name, float value) const; };#endif我们用了几个预处理器指令在头文件的顶部。使用这些小代码行可以通知编译器仅包含并编译此头文件如果尚未包含该头文件即使多个文件包含着色器头也是如此。这可以防止链接冲突。         着色器类保存着色器程序的ID。它的构造函数分别需要顶点着色器和片段着色器源代码的文件路径我们可以将其作为简单文本文件存储在磁盘上。为了添加一些额外的内容我们还添加了一些实用函数来让我们的生活稍微轻松一些使用激活着色器程序并且所有放...函数查询统一位置并设置其值。 五、从文件中读取         我们使用 C 文件流将文件内容读取到多个string对象中 Shader(const char* vertexPath, const char* fragmentPath) {// 1. retrieve the vertex/fragment source code from filePathstd::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;// ensure ifstream objects can throw exceptions:vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);try {// open filesvShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;// read files buffer contents into streamsvShaderStream vShaderFile.rdbuf();fShaderStream fShaderFile.rdbuf(); // close file handlersvShaderFile.close();fShaderFile.close();// convert stream into stringvertexCode vShaderStream.str();fragmentCode fShaderStream.str(); }catch(std::ifstream::failure e){std::cout ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ std::endl;}const char* vShaderCode vertexCode.c_str();const char* fShaderCode fragmentCode.c_str();[...]接下来我们需要编译并链接着色器。请注意我们还会检查编译/链接是否失败如果失败则打印编译时错误。这在调试时非常有用您最终将需要这些错误日志 // 2. compile shaders unsigned int vertex, fragment; int success; char 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 ID glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); // print linking errors if any glGetProgramiv(ID, GL_LINK_STATUS, success); if(!success) {glGetProgramInfoLog(ID, 512, NULL, infoLog);std::cout ERROR::SHADER::PROGRAM::LINKING_FAILED\n infoLog std::endl; }// delete the shaders as theyre linked into our program now and no longer necessary glDeleteShader(vertex); glDeleteShader(fragment);这使用函数很简单 void use() { glUseProgram(ID); } 对于任何统一设置函数也类似 void setBool(const std::string name, bool value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); } void setInt(const std::string name, int value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void setFloat(const std::string name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } 这样我们就有了一个完整的着色器类。使用着色器类相当简单我们创建一个着色器对象一次从那时起就开始使用它 Shader ourShader(path/to/shaders/shader.vs, path/to/shaders/shader.fs); [...] while(...) {ourShader.use();ourShader.setFloat(someUniform, 1.0f);DrawStuff(); }在这里我们将顶点和片段着色器源代码存储在两个名为shader.vs和的文件中shader.fs。您可以随意命名着色器文件我个人认为这些扩展.vs非常.fs直观。 您可以在此处找到使用我们新创建的着色器类的 源代码。请注意您可以单击着色器文件路径来查找着色器的源代码。 六、练习 调整顶点着色器使三角形颠倒解决方案。通过统一指定水平偏移并使用此偏移值将三角形移动到顶点着色器中的屏幕右侧解决方案。使用关键字将顶点位置输出到片段着色器out并将片段的颜色设置为等于该顶点位置查看如何在三角形上插值顶点位置值。一旦你成功做到了这一点尝试回答以下问题为什么三角形的左下角是黑色的解决方案。
http://www.pierceye.com/news/471031/

相关文章:

  • 二手交易网站建设方案ppt网站备案的作用
  • 北京行业网站建设临沂谁会做网站
  • 网站备案 游戏修改wordpress字体
  • 福建微网站建设价格宝山专业网站建设
  • 做采集网站难不关键词做网站名字
  • 怎么做律师事务所的网站用凡科做网站好吗
  • 免费做网站公司ydwzjs政务网站的建设
  • 企业网站设计总结西安做网站哪里便宜
  • wordpress 电影下载站济南最新消息
  • 怎样做企业的网站公司部门解散
  • 三亚中国检科院生物安全中心门户网站建设什么是响应式网站
  • 为什么要建设公司网站怎么制作图片视频和配音乐
  • 建设项目环境影响登记表备案系统网站论坛门户网站开发
  • 铁岭网站建设建设云企业服务平台
  • 响应式网站制作方法泰安明航网络科技有限公司
  • 建设网站需要几级安全等保深圳网站开发招聘
  • 无锡网站建设制作公司甘肃省建设工程网站
  • 广州微信网站建设哪家好公司网站排名优化手段
  • 深圳市路桥建设集团有限公司招标采购网站crntos wordpress
  • 广告网站制作报价深圳建筑设计平台网站
  • 网站ns记录南宁企业建站模板
  • 网站服务建设目前做哪些网站能致富
  • 专业网站定制公司深圳网页制作服务
  • 白云网站(建设信科网络)网页工具在哪里
  • 食品网站策划网站建设送企业邮箱吗
  • 天津自贸区建设局网站手机网站导航设计
  • 企业网站建设制作大连网站建设吗
  • 做网页兼职网站有哪些建设网站需要花费
  • 如何快速写一个网站黄页网络的推广软件下载
  • 网站建设公司注册enfold wordpress