着色器
文章推薦指數: 80 %
GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。
着色器的开头总是要声明版本,接着是输入和输出变量、uniform和 main 函数。
每个着色器的入口 ...
LearnOpenGL-CN
主页
简介
入门
OpenGL
创建窗口
你好,窗口
你好,三角形
着色器
着色器
GLSL
数据类型
输入与输出
Uniform
更多属性!
我们自己的着色器类
从文件读取
练习
纹理
变换
坐标系统
摄像机
复习
光照
颜色
光照基础
材质
光照贴图
投光物
多光源
复习
加载模型
Assimp
网格
模型
高级OpenGL
深度测试
模板测试
混合
面剔除
帧缓冲
立方体贴图
高级数据
高级GLSL
几何着色器
实例化
抗锯齿
高级光照
高级光照
Gamma校正
阴影
阴影映射
点阴影
CSM
法线贴图
视差贴图
HDR
泛光
延迟着色法
SSAO
实战
调试
文字渲染
2D游戏
Breakout
准备工作
渲染精灵
粒子
LearnOpenGL-CN
Docs»
入门»
着色器
着色器
原文
Shaders
作者
JoeyDeVries
翻译
Django
校对
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来获取具体的上限:
GLintnrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&nrAttributes);
std::cout<
#include
这些预处理指令会告知你的编译器只在它没被包含过的情况下才包含和编译这个头文件,即使多个文件都包含了这个着色器头文件。
它是用来防止链接冲突的。
着色器类储存了着色器程序的ID。
它的构造器需要顶点和片段着色器源代码的文件路径,这样我们就可以把源码的文本文件储存在硬盘上了。
我们还添加了一个Use函数,它其实不那么重要,但是能够显示这个自造类如何让我们的生活变得轻松(虽然只有一点)。
从文件读取
我们使用C++文件流读取着色器内容,储存到几个string对象里:
Shader(constGLchar*vertexPath,constGLchar*fragmentPath)
{
//1.从文件路径中获取顶点/片段着色器
std::stringvertexCode;
std::stringfragmentCode;
std::ifstreamvShaderFile;
std::ifstreamfShaderFile;
//保证ifstream对象可以抛出异常:
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try
{
//打开文件
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstreamvShaderStream,fShaderStream;
//读取文件的缓冲内容到流中
vShaderStream<
使用这个着色器类很简单;只要创建一个着色器对象,从那一点开始我们就可以开始使用了:
ShaderourShader("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的文件。
你可以使用自己喜欢的名字命名着色器文件;我自己觉得用.vs和.frag作为扩展名很直观。
源码:使用新着色器类的程序,着色器类,顶点着色器,和片段着色器。
练习
修改顶点着色器让三角形上下颠倒:参考解答
使用uniform定义一个水平偏移量,在顶点着色器中使用这个偏移量把三角形移动到屏幕右侧:参考解答
使用out关键字把顶点位置输出到片段着色器,并将片段的颜色设置为与顶点位置相等(来看看连顶点位置值都在三角形中被插值的结果)。
做完这些后,尝试回答下面的问题:为什么在三角形的左下角是黑的?:参考解答
ReadtheDocs
延伸文章資訊
- 1着色器
GLSL是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。 着色器的开头总是要声明版本,接着是输入和输出变量、uniform和 main 函数。每个着色器的入口 ...
- 2Uniform (GLSL) - OpenGL Wiki - Khronos Group
Uniform (GLSL) ... Shader stages: ... A uniform is a global Shader variable declared with the "un...
- 3GLSL Tutorial – Uniform Variables - Lighthouse3d.com
GLSL Tutorial – Uniform Variables ... Uniform variables act as constants, at least for the durati...
- 4一起幫忙解決難題,拯救IT 人的一天
GLSL(OpenGL Shading Language Language)是OpenGL 的Shader 語言,它長得有點像C語言, ... uniform type uniform_name...
- 5GLSL 三种变量类型(uniform,attribute和varying)理解 - 简书
1.uniform变量uniform变量是外部程序传递给(vertex和fragment)shader的变量。因此它是application通过函数glUniform**(...