美文网首页
图形学和OpenGL

图形学和OpenGL

作者: Jassi | 来源:发表于2020-12-03 20:42 被阅读0次

    OpenGL

    • 开放图形库或者“开放式图形库” 是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口规范(API规范).
    • 是Khronos Group开发维护的一个规范,它主要为我们定义了用来操作图形和图片的一系列函数的API,需要注意的是OpenGL本身并非API。
    • GPU的硬件开发商则需要提供满足OpenGL规范的实现,这些实现通常被称为“驱动”,它们负责将OpenGL定义的API命令翻译为GPU指令。显卡驱动中包括了对OpenGL规范的实现。

    竞品:

    metal 苹果的

    vulkan

    directX/direct3D 微软的(对应编程语言HLSL)

    shader

    https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/

    着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。

    https://blog.csdn.net/onafioo/article/details/38983197

    着色程序分为两类:vertex shader program(顶点着色程序)和fragment shader program(片断着色程序)。对应GPU上的两个组件:Programmable Vertex Processor(可编程顶点处理器,又称为顶点着色器)和 Programmable Fragment Processor(可编程片断处理器,又称为片断着色器)。顶点和片段处理器被分离成可编程单元,可编程顶点处理器是一个硬件单元,可以运行顶点程序,而可编程片段处理器则是一个可以运行片段程序的单元。

    顶点和片段处理器都拥有非常强大的并行计算能力

    什么是片断?片断和像素有什么不一样?所谓片断就是所有的三维顶点在光栅化(矢量图转成位图)之后的数据集合,这些数据还没有经过深度值比较,而屏幕显示的像素都是经过深度比较的。

    顶点着色器控制顶点坐标转换过程;片段着色器控制像素颜色计算过程。这样就区分出顶点着色程序和片段着色程序的各自分工:Vertex program负责顶点坐标变换和几何计算;Fragment program负责像素颜色计算;前者的输出是后者的输入

    GLSL

    声明

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

    着色器的开头总是要声明版本,接着是输入和输出变量、uniform和函数。每个着色器的入口点都是函数,在这个main函数中我们处理所有的输入变量,并将结果输出到输出变量中。

    #version version_number

    in type in_variable_name;

    in type in_variable_name;

    out type out_variable_name;

    uniform type uniform_name;

    int main()

    {

    // 处理输入并进行一些图形操作

    ...

    // 输出处理过的结果到输出变量

    out_variable_name = weird_stuff_we_processed;

    }

    分类:

    • vertexShader: 数量有限 跟硬件有关,一般不少于16个

      fragmentShader

    • 着色器是各自独立的小程序,每个着色器都有输入和输出,并进行数据交流和传递。一个输出变量与下一个着色器阶段的输入匹配(名字相同),它就会传递下去。

    vertexShader从顶点数据中直接接收输入,使用​location​这一元数据指定输入变量。顶点着色器需要为它的输入提供一个额外的​layout​标识,这样我们才能把它链接到顶点数据​layout (location = 0)​。在OpenGL代码中使用查询属性位置值(Location)

    fragment,它需要一个​vec4​颜色输出变量,因为片段着色器需要生成一个最终输出的颜色。如果你在片段着色器没有定义输出颜色,OpenGL会把你的物体渲染为黑色(或白色)。

    数据类型:

    • 基础类型 ​int​、​float​、​double​、​uint、bool​

    • 容器类型:Vector、Matrix

    Vector类型:

    • 可以包含1-4个基础类型的分量

    <colgroup><col width="395"><col width="395"></colgroup>
    | 类型 | 含义 |
    | vecn | 包含n个float分量的默认向量 |
    | bvecn | 包含n个bool分量的向量 |
    | ivecn | 包含n个int分量的向量 |
    | uvecn | 包含n个unsigned int分量的向量 |
    | dvecn | 包含n个double分量的向量 |

    重组swizzling

    一个向量的分量可以通过​vec.x​这种方式获取,这里​x​是指这个向量的第一个分量。你可以分别使用​.x​、​.y​、​.z​和​.w​来获取它们的第1、2、3、4个分量。GLSL也允许你对颜色使用​rgba​,或是对纹理坐标使用​stpq​访问相同的分量。

    向量这一数据类型也允许一些有趣而灵活的分量选择方式,叫做(Swizzling)。重组允许这样的语法:

    vec2 someVec;

    vec4 differentVec = someVec.xyxx;

    vec3 anotherVec = differentVec.zyw;

    vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

    你可以使用上面4个字母任意组合来创建一个和原来向量一样长的(同类型)新向量,只要原来向量有那些分量即可;然而,你不允许在一个vec2向量中去获取.z元素。我们也可以把一个向量作为一个参数传给不同的向量构造函数,以减少需求参数的数量:

    vec2 vect = vec2(0.5, 0.7);

    vec4 result = vec4(vect, 0.0, 0.0);

    vec4 otherResult = vec4(result.xyz, 1.0);

    uniform

    是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。首先,uniform是(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

    输入输出

    vertexShader与fragShader链接

    **顶点着色器**

    #version 330 core

    layout (location = 0) in vec3 aPos; // 位置变量的属性位置值为0

    out vec4 vertexColor; // 为片段着色器指定一个颜色输出

    void main()

    {

    gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数

    vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色

    }

    **片段着色器**

    #version 330 core

    out vec4 FragColor;

    in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同)

    void main()

    {

    FragColor = vertexColor;

    }

    如何使用GLSL

    使用canvas.getContext('webgl'), 就可以使用gl实例的语法了 eg

    .createShader(shaderType)

    .shaderSource(shaderInstance, option)

    .compileShader(shaderInstance)

    .createProgram()

    .attachShader(programInstance, shaderInstance)

    .linkProgram(programInstance)

    .useProgram(programInstance)

    .createBuffer()

    .bindBuffer(bufferType, bufferInstance)

    .bufferData(bufferType, data)

    .vertexAttribArrary()

    .enableVertexAttribArray(position)

    .drawArrays()

    可以解决前端的什么问题呢?

    生成图片、修改图片

    减少引入切图

    结论

    但是使用OpenGL绘制图形还是很难的(很多时候是一个数学问题)吧 所以权衡一下把

    相关文章

      网友评论

          本文标题:图形学和OpenGL

          本文链接:https://www.haomeiwen.com/subject/gesvwktx.html