美文网首页
LearnOpenGL 一些基本的概念

LearnOpenGL 一些基本的概念

作者: li_礼光 | 来源:发表于2020-09-06 17:49 被阅读0次

CPU和GPU的区别 : CPU GPU 的区别是什么?

这里重点记录下对GPU的理解, 因为OpenGl是针对于GPU编程, 所以就不能以CPU的编程思维对GPU编程, 因为涉及到后面的一些Shader编程, 函数的调用, 参数的传递, 会对新手来说有些绕.

CPU和GPU编程的不同 :
CPU我们可以从多线程的角度, 线程之间的通信操作,串行or并行的而方式执行任务, GPU不同的是, GPU的任务都是以并行的方式, 都是单线程的执行方式. 所以,很少的cache. 缓存的目的不是保存后面需要访问的数据的.

也可以简单粗暴的理解 : 这个是CPU和GPU物理结构决定的.



Shader编程

对于OpenGL的最终作用, 我们是把我们需要的图像或者一些3D模型投影到屏幕上,我们所要做的就是这么一个事情.

什么是Shader
Shader其实就是专门用来渲染图形的一种技术,通过shader,我们可以自定义显卡渲染画面的算法,使画面达到我们想要的效果。小到每一个像素点,大到整个屏幕,比如下面这两个游戏内比较常见的效果。

简单粗暴的理解
比如在Unity中创建一个材质球, 给材质球设置颜色, 设置纹理.
我们可以通过直接在Unity的可视化工具上选择我们需要设置的内容.
我们也可以通过创建一个Shader文件, 在Shader中创建一些对应的属性, 比如颜色, 大小等等. 从代码的层面去操作.

了解Shader中的材质球 和 纹理之间的概念. 代码层面可以理解为对应OpenGL中的program 和 shader.

OpenGL的可编程管线, 就是让我们可以针对于顶点着色器和片元着色器, 通过编写对应的Shader, 顶点数据怎么加载到顶点着色器中, 纹理怎么加载到片元着色器中, 怎么处理buffer数据到最终显示到屏幕上的一个事情.

建议 : 可以简单先从Shader编程学学一些基本概念, 基本操作.再来学OpenGL会快的多.



可编程管线

网上保存了一个比较好理解的图形:

渲染流程

简单粗暴的理解流程 :

顶点着色器 -> 光栅化 -> 测试与混合 -> 片元着色器 -> buffer缓冲区 -> 显示到屏幕

这里是一个极为精简的流程图.
对于可编程管线, 我们可以操作的只有 顶点着色器片元着色器. 可以先简单有个概念.

顶点着色器

它可以用于执⾏自定义计算,实施新的变换,照明或者传统的固定功能所不允许的基于顶点的效果,例如:

矩阵变换位置
计算光照公式生成逐顶点颜色
⽣成/变换纹理坐标
片元着色器

它可以用于图片/视频/图形中每个像素的颜色填充(比如给视频添加滤镜,实际上就是将视频中每个图片的像素点颜色填充进行修改.)

计算颜⾊
获取纹理值
往像素点中填充颜色值(纹理值/颜色值);

简单粗暴的就是:
(顶点)一个是处理, 这些图像在屏幕上显示的坐标位置的问题.
(片元)一个是处理, 这些图像在屏幕上显示的长什么样的问题









看到后面的Shader程序. 应该会有这么写疑问 :一些固定的值是怎么来得.
可以往回参考下面的内容.

比如 :

顶点着色器程序

/// 着色器程序之间的数据传递
static char *MyTextureVertexShaderStr = SHADER(
    \#version 330 core\n
                               
    layout (location = 0) in vec3 position; //顶点数据源输入
    layout (location = 1) in vec3 color; //颜色数据源输入
    layout (location = 2) in vec2 texCoords; //纹理数据源输入(2D)

    out vec2 vertexTexCoords;//纹理输出
    out vec4 vertexColor;//颜色输出

    void main()
    {
        gl_Position = vec4(position, 1.0f);//坐标位置
        vertexColor = vec4(color, 1.0f); //输出给片元着色器
        vertexTexCoords = texCoords;
    }
);

片元着色器程序

//片元着色器程序
static char *MyTextureFragmentShaderSrc = SHADER(
    \#version 330 core\n
                                        
    in vec2 vertexTexCoords;//纹理输入(从顶点)
    in vec4 vertexColor;//颜色输入(从顶点)
                        
    uniform sampler2D myTexture;//全局myTexture

    out vec4 color;//颜色输出
    out vec4 FragColor;//纹理输出
                                                 
    void main()
    {
        color = vertexColor;
        FragColor = texture(myTexture, vertexTexCoords);
    }
);

对于gl_Position , color, FragColor如果有疑惑. 这里是根据GLSL基础量的定义来的.

gl_Position 所有的顶点着色器都必须写这个值。
gl_Color 输入属性-表示顶点的主颜色
gl_FragColor 输出的颜色用于随后的像素操作

参考 # GLSL 基础量定义

修饰符

变量的声明可以使用如下的修饰符。

修饰符 描述
const 常量值必须在声明是初始化。它是只读的不可修改的。
attribute 表示只读的顶点数据,只用在顶点着色器中。数据来自当前的顶点状态或者顶点数组。它必须是全局范围声明的,不能再函数内部。一个attribute可以是浮点数类型的标量,向量,或者矩阵。不可以是数组或则结构体
uniform 一致变量。在着色器执行期间一致变量的值是不变的。与const常量不同的是,这个值在编译时期是未知的是由着色器外部初始化的。一致变量在顶点着色器和片段着色器之间是共享的。它也只能在全局范围进行声明。
varying 顶点着色器的输出。例如颜色或者纹理坐标,(插值后的数据)作为片段着色器的只读输入数据。必须是全局范围声明的全局变量。可以是浮点数类型的标量,向量,矩阵。不能是数组或者结构体。
centorid varying 在没有多重采样的情况下,与varying是一样的意思。在多重采样时,centorid varying在光栅化的图形内部进行求值而不是在片段中心的固定位置求值。
invariant (不变量)用于表示顶点着色器的输出和任何匹配片段着色器的输入,在不同的着色器中计算产生的值必须是一致的。所有的数据流和控制流,写入一个invariant变量的是一致的。编译器为了保证结果是完全一致的,需要放弃那些可能会导致不一致值的潜在的优化。除非必要,不要使用这个修饰符。在多通道渲染中避免z-fighting可能会使用到。
in 用在函数的参数中,表示这个参数是输入的,在函数中改变这个值,并不会影响对调用的函数产生副作用。(相当于C语言的传值),这个是函数参数默认的修饰符
out 用在函数的参数中,表示该参数是输出参数,值是会改变的。
inout 用在函数的参数,表示这个参数即是输入参数也是输出参数。

内置变量

内置变量可以与固定函数功能进行交互。在使用前不需要声明。顶点着色器可用的内置变量如下表:

名称 类型 描述
gl_Color vec4 输入属性-表示顶点的主颜色
gl_SecondaryColor vec4 输入属性-表示顶点的辅助颜色
gl_Normal vec3 输入属性-表示顶点的法线值
gl_Vertex vec4 输入属性-表示物体空间的顶点位置
gl_MultiTexCoordn vec4 输入属性-表示顶点的第n个纹理的坐标
gl_FogCoord float 输入属性-表示顶点的雾坐标
gl_Position vec4 输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。
gl_ClipVertex vec4 输出坐标,用于用户裁剪平面的裁剪
gl_PointSize float 点的大小
gl_FrontColor vec4 正面的主颜色的varying输出
gl_BackColor vec4 背面主颜色的varying输出
gl_FrontSecondaryColor vec4 正面的辅助颜色的varying输出
gl_BackSecondaryColor vec4 背面的辅助颜色的varying输出
gl_TexCoord[] vec4 纹理坐标的数组varying输出
gl_FogFragCoord float 雾坐标的varying输出

片段着色器的内置变量如下表:

名称 类型 描述
gl_Color vec4 包含主颜色的插值只读输入
gl_SecondaryColor vec4 包含辅助颜色的插值只读输入
gl_TexCoord[] vec4 包含纹理坐标数组的插值只读输入
gl_FogFragCoord float 包含雾坐标的插值只读输入
gl_FragCoord vec4 只读输入,窗口的x,y,z和1/w
gl_FrontFacing bool 只读输入,如果是窗口正面图元的一部分,则这个值为true
gl_PointCoord vec2 点精灵的二维空间坐标范围在(0.0, 0.0)到(1.0, 1.0)之间,仅用于点图元和点精灵开启的情况下。
gl_FragData[] vec4 使用glDrawBuffers输出的数据数组。不能与gl_FragColor结合使用。
gl_FragColor vec4 输出的颜色用于随后的像素操作
gl_FragDepth float 输出的深度用于随后的像素操作,如果这个值没有被写,则使用固定功能管线的深度值代替

相关文章

  • LearnOpenGL 一些基本的概念

    CPU和GPU的区别 : CPU 和 GPU 的区别是什么? 这里重点记录下对GPU的理解, 因为OpenGl是...

  • LearnOpenGL 概念词汇表

    在你学过的最后几个教程中,你学习了有关颜色,冯氏光照模型(包括环境,漫反射,镜面反射光照),对象材质,可配置的光照...

  • iOS OpenGL ES 学习笔记(一)

    我基本是看https://learnopengl-cn.github.io/这个教程,和落影loyinglin的博...

  • LearnOpenGL 入门篇

    官方教程 :LearnOpenGL-CN[https://learnopengl-cn.readthedocs.i...

  • OpenGL学习资料和记录

    学习资料 OpenGL: LearnOpenGL[https://learnopengl.com/] 计算机图形/...

  • HDR

    参考资料 LearnOpenGL - HDR[https://learnopengl.com/Advanced-L...

  • opengl相关资料

    推荐度较高的opengl教程:《learnopengl》中文版https://learnopengl-cn.git...

  • 教程

    LearnOpenGL CN

  • 一些基本概念

    .前端 前端是网站和用户交互的主要接口。 开发语言为HTML、 CSS、JS. ①HTML 一种文本、图片、链...

  • 一些基本概念

    Info.plist 文件 项目的配置文件,项目中其他Plist文件不能带有“Info”这个字眼。常见属性Loca...

网友评论

      本文标题:LearnOpenGL 一些基本的概念

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