OpenGL ES 学习 -- 渲染模式和GLSL
Posted 夏至的稻穗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL ES 学习 -- 渲染模式和GLSL相关的知识,希望对你有一定的参考价值。
上一章,我们学习了 OpenGL 的基本知识,这一章,一起学习OpenGL的渲染模式和渲染语言GLSL。
一. 渲染流程
OpenGL的渲染流程如下图所示:
从这里看出,OpenGL 需要使用顶点着色器,先绘制好轮廓,再通过图元装配,将顶点转换成图元,然后通过光栅化,将图片这种矢量图形,转成为栅格化数据,最后,使用片段着色器,将光栅化的数据,每一个像素进行运算,并绘制上对应的颜色,然后再展示到屏幕中。
大致的步骤为:
- 确定顶点的位置,通过顶点绘制指定的图形。
- 为图形上色,可以是纯色,渐变色,或者图片纹理
- 将图形加载到缓冲区,framebuffer 中,展示到屏幕
而我们开发的重点,需要重点关注,顶点着色器,片段着色器,将数据传递到着色器上这三个重点就可以了。
二. 基本概念
-
管线: 它是一系列数据处理的过程,是显示芯片内部(GPU)处理图形信号相互独立的并行处理单元。
-
顶点程序:用于描述顶点操作的可执行文件/着色器源代码
-
图元片段: OpenGL ES 只有三种图元,点、线,三角形,它会把顶点数据数据计算成一个个图元,在这个阶段会进行裁减,透视分割和其他变换操作。
-
着色器 Shader:用于秒速如何绘制图形图像的具体环节,分为顶点着色器,片段着色器。
-
光栅化:就是将图元转换成一个二维片段的过程,这些转化由片段着色器处理,这些二维片段,就是屏幕上课绘制的像素。
-
纹理:可以理解成一张图片,用着色器在上面涂上不同的东西。
三. 坐标
与 android 左边西不同,GL 的其实位置是在屏幕的中心,以(0,0)为中心店,x 坐标从做到有,y 从下到上,在 [-1,1] 之前取值,再映射到屏幕,而超出 [-1,1] 之外的,不会在屏幕上显示。如下图:
四. GLSL 语言
GLSL (OpenGL Shading Language)是着色器程序的编程语言,该程序会在 GPU 上执行,使得渲染管线具有可编程性。这里,你可以先简单浏览,等在编写 GLSL 的语言的时候,再来看一下。
4.1 GLSL 特有语法
GLSL 与 C 语言而非常相似,有基本的类型、函数、结构体,但没有指针;当然也有自己的一些特殊类型。
4.1.1 基本类型
在计算机图形中,向量和矩阵是变换的基础,这两种数据类型也是 GLSL 的核心,它的基本类型如下:
- 浮点向量:vec2 ,vec3 ,vec4
- 整数向量:ivec2 ,ivec3 ,ivec4
- 无符号整型向量:uvec2 ,uvec3 ,uvec4
- boolean向量:bvec2 ,bvec3 ,bvec4
- 浮点矩阵:mat2,mat3,mat4,mat2x3…
- 二维纹理句柄:sampler2D
4.1.2 修饰符
- const:(只读) 常量变量
- attribute:只能用于顶点着色器,用于经常更改的信息
- uniform: (始终如一的)用于不经常更改的信息,可用于顶点和片元着色器
- varying:(易变的)用于修饰从顶点着色器向片元着色器传递变量。
更多的解释,可以参考:https://zhuanlan.zhihu.com/p/52807564
4.2 内置变量
OpenGL 中,有几个内置变量,最常见的是在顶点着色器和片段着色器中
- 顶点着色器(Vectex Shader):gl_position(位置) 和 gl_pointSize (大小)
- 片段着色器(Fragment Shader):gl_FragColor (颜色值)
4.3 函数和内置函数
GLSL 的函数使用,与 C 语言基本一直,在定义函数之前先申明类型。不同之处,在于 GLSL 在函数参数上提供了特殊的限定符(修饰符),这个跟 aidl 有点像,如:
- in:默认模式,相当于传入参数只是 in 实参的一份拷贝,修改的值不会影响 in 参数本身,相当于java的 get
- out:相当于 wirte-only,可写不可读,相当于 java 的set方法
- inpuot:可读可写模式,直接改到实参,可以理解有 get 和set 方法。
GLSL 提供内置函数还是挺方便的,常见的有:
- abs:绝对值
- floor:向下取整
- ceil:向上取整
- mod:取模
- min:最小
- max:最大
- clamp:中间值
- dot:计算两个向量的点积
- pow:计算标量的幂次
4.4 GLSL 编写工具
在 Android studio 中,下载 GLSL 的插件,就可以编写后,再拷贝到着色器代码了,有代码提示真的很不错:
OpenGL 的渲染框架
接下来,看看 GLSL 是如何把 着色器的值传递给 OpenGL 的渲染管线的,如下图:
从上面可以看到,管线可以分为 client 和 server:
Client:
这里是我们赋予着色器参数的动态值,以及调用的 OpenGL api ,这里指我们的程序代码。
Server:
Server 是整个渲染的核心,它运行再 GPU,Client 和 Server 只能通过 Attributes ,Uniforms 等类型通信。然后再通过着色器 Shader 将数据绘制渲染出来。
参考:
https://mp.weixin.qq.com/s?__biz=MzU5NjkxMjE5Mg==&mid=2247483771&idx=1&sn=9b122a361188aa4cc0d75549be0ee4a4&chksm=fe5a3054c92db942d350306739c2c775c95d107b8f2a213d6ddc9cbc5c042c702dc1d36c3581&scene=21#wechat_redirect
https://www.jianshu.com/p/48c52f862f42
https://www.jianshu.com/p/a818684333f2
https://zhuanlan.zhihu.com/p/52807564
以上是关于OpenGL ES 学习 -- 渲染模式和GLSL的主要内容,如果未能解决你的问题,请参考以下文章
openGL之API学习(一七七)opengl gles glsl glsl es版本对应关系
我的OpenGL学习进阶之旅OpenGL ES 着色语言的IDE插件(Android Studio和Visutal Studio)以及常见GLSL文件扩展名介绍
我的OpenGL学习进阶之旅OpenGL ES 着色语言的IDE插件(Android Studio和Visutal Studio)以及常见GLSL文件扩展名介绍
OPENGL ES 2.0 知识串讲 ——GLSL 语法(II)
OPENGL ES 2.0 知识串讲 ——GLSL 语法(II)
我的OpenGL学习进阶之旅关于OpenGL ES 绘制中使用到的 Android中GLSurfaceView的两种渲染模式