着色器

文章推薦指數: 80 %
投票人數:10人

着色器是使用一种叫GLSL的类C语言写成的。

GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。

着色器的开头总是要 ... Togglenavigation LearnOpenGLCN 主页 目录 简介 入门 OpenGL 创建窗口 你好,窗口 你好,三角形 着色器 纹理 变换 坐标系统 摄像机 复习 光照 颜色 基础光照 材质 光照贴图 投光物 多光源 复习 模型加载 Assimp 网格 模型 高级OpenGL 深度测试 模板测试 混合 面剔除 帧缓冲 立方体贴图 高级数据 高级GLSL 几何着色器 实例化 抗锯齿 高级光照 高级光照 Gamma校正 阴影 阴影映射 点阴影 CSM 法线贴图 视差贴图 HDR 泛光 延迟着色法 SSAO PBR 理论 光照 IBL 漫反射辐照 镜面IBL 实战 调试 文本渲染 2D游戏 Breakout 准备工作 渲染精灵 关卡 碰撞 球 碰撞检测 碰撞处理 粒子 后期处理 道具 音效 渲染文本 结语 历史存档 代码仓库 搜索 上一节 下一节 GitHub 支持原作者 着色器 GLSL 数据类型 输入与输出 Uniform 更多属性! 我们自己的着色器类 从文件读取 练习 着色器 原文 Shaders 作者 JoeyDeVries 翻译 Django,Krasjet,Geequlim 校对 暂未校对 在HelloTriangle教程中提到,着色器(Shader)是运行在GPU上的小程序。

这些小程序为图形渲染管线的某个特定部分而运行。

从基本意义上来说,着色器只是一种把输入转化为输出的程序。

着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。

前面的教程里我们简要地触及了一点着色器的皮毛,并了解了如何恰当地使用它们。

现在我们会用一种更加广泛的形式详细解释着色器,特别是OpenGL着色器语言(GLSL)。

GLSL 着色器是使用一种叫GLSL的类C语言写成的。

GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。

着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。

每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中。

如果你不知道什么是uniform也不用担心,我们后面会进行讲解。

一个典型的着色器有下面的结构: #versionversion_number intypein_variable_name; intypein_variable_name; outtypeout_variable_name; uniformtypeuniform_name; intmain() { //处理输入并进行一些图形操作 ... //输出处理过的结果到输出变量 out_variable_name=weird_stuff_we_processed; } 当我们特别谈论到顶点着色器的时候,每个输入变量也叫顶点属性(VertexAttribute)。

我们能声明的顶点属性是有上限的,它一般由硬件来决定。

OpenGL确保至少有16个包含4分量的顶点属性可用,但是有些硬件或许允许更多的顶点属性,你可以查询GL_MAX_VERTEX_ATTRIBS来获取具体的上限: intnrAttributes; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&nrAttributes); std::cout<;//包含glad来获取所有的必须OpenGL头文件 #include #include #include #include classShader { public: //程序ID unsignedintID; //构造器读取并构建着色器 Shader(constchar*vertexPath,constchar*fragmentPath); //使用/激活程序 voiduse(); //uniform工具函数 voidsetBool(conststd::string&name,boolvalue)const; voidsetInt(conststd::string&name,intvalue)const; voidsetFloat(conststd::string&name,floatvalue)const; }; #endif Important 在上面,我们在头文件顶部使用了几个预处理指令(PreprocessorDirectives)。

这些预处理指令会告知你的编译器只在它没被包含过的情况下才包含和编译这个头文件,即使多个文件都包含了这个着色器头文件。

它是用来防止链接冲突的。

着色器类储存了着色器程序的ID。

它的构造器需要顶点和片段着色器源代码的文件路径,这样我们就可以把源码的文本文件储存在硬盘上了。

除此之外,为了让我们的生活更轻松一点,还加入了一些工具函数:use用来激活着色器程序,所有的set…函数能够查询一个unform的位置值并设置它的值。

从文件读取 我们使用C++文件流读取着色器内容,储存到几个string对象里: Shader(constchar*vertexPath,constchar*fragmentPath) { //1.从文件路径中获取顶点/片段着色器 std::stringvertexCode; std::stringfragmentCode; std::ifstreamvShaderFile; std::ifstreamfShaderFile; //保证ifstream对象可以抛出异常: vShaderFile.exceptions(std::ifstream::failbit|std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit|std::ifstream::badbit); try { //打开文件 vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstreamvShaderStream,fShaderStream; //读取文件的缓冲内容到数据流中 vShaderStream<



請為這篇文章評分?