Opengl ES——着色器(opengles着色器教程)

前言

在前面我们介绍了 Opengl ES之EGL环境搭建,在后面的例子中,我们将无可避免地需要使用到着色器。而着色器才是Opengl的灵魂所在,有了着色器才有了Opengl天马行空的世界。

C 音视频开发学习资料点击领取音视频开发(资料文档 视频教程 面试题)(FFmpeg WebRTC RTMP RTSP HLS RTP)

图形渲染管线

要想理解什么是着色器以及着色器的作用就必须先了解下图形渲染管线。

在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,这导致OpenGL的大部分工作都是关于把3D坐标转变为适应你屏幕的2D像素。将OpenGL中的3D世界转换到屏幕窗口中的2D世界中展示出来的过程称为图形渲染管线。 也可以说将一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程就是图形渲染管线。图形渲染管线可以被划分为两个主要部分:第一部分把你的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素。

图形渲染管线可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。所有这些阶段都是高度专门化的(它们都有一个特定的函数),并且很容易并行执行。正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。这些小程序叫做着色器(Shader)。

着色器

着色器是进行三维图形学编程的先进方法,从某种意义上来说 Shader 的出现是图形学中的一种”退步”,因为在这之前所有的功能都直接由固定管线提供,而开发人员只需要为其指定参数(如光照属性、旋转角度等),但是由于 Shader 的出现这些功能现在都需要开发者自己通过 Shader 实现。 尽管如此,这种可编程性能够提供给开发者更多的灵活性和创造性。

下图是Opengl图形渲染管线的抽象过程:

Opengl ES——着色器(opengles着色器教程)

蓝色部分代表的是我们可以注入自定义的着色器的部分。也就说我们通过自定义顶点着色器、几何着色器和片段着色器就可以实现我们想要各种效果,同时几何着色器又是可选的,一般使用默认的即可,因此我们只需将重点放在顶点着色器和片段着色器即可。

C 音视频开发学习资料点击领取音视频开发(资料文档 视频教程 面试题)(FFmpeg WebRTC RTMP RTSP HLS RTP)

下面参照上图,简单介绍一下各个阶段的主要功能职责:

  • 顶点着色器
    图形渲染管线的第一个部分是顶点着色器(Vertex Shader),它把一个单独的顶点作为输入。顶点着色器主要的目的是把3D坐标转为另一种3D坐标,同时顶点着色器允许我们对顶点属性进行一些基本处理,例如矩阵变换等。
  • 图元装配
    图元装配阶段将顶点着色器输出的所有顶点作为输入,并所有的点装配成指定图元的形状。例如绘制正方形时,就是通过两个三角形组装成正方形,绘制多面体时,就是将n多个三角形组装成多面体的过程。
  • 几何着色器
    图元装配阶段的输出会传递给几何着色器。几何着色器把图元形式的一系列顶点的集合作为输入,它可以通过产生新顶点构造出新的(或是其它的)图元来生成其他形状。
  • 光栅化
    几何着色器的输出会被传入光栅化阶段,这里它会把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素,用来提升执行效率。
  • 片段着色器
    片段着色器的主要目的是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色。
  • 测试与混合
    这个阶段检测片段的对应的深度(和模板(Stencil))值,用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查alpha值(alpha值定义了一个物体的透明度)并对物体进行混合(Blend)。 所以,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个三角形的时候最后的像素颜色也可能完全不同。

GLSL

OpenGL着色器是用OpenGL着色器语言(OpenGL Shading Language, GLSL)写成的。

在OpenGL中,我们必须定义至少一个顶点着色器和一个片段着色器,因为GPU中没有默认的顶点/片段着色器。

我们来看一个最简单的顶点着色器的例子:

#version 300 esin vec4 aPos;void main(){ gl_Position = aPos;}

GLSL的语法与C语言很类似,相信有过编程经验的伙伴们大概都能看懂以上这个着色器。

顶点着色器的第一行#version 300 es首先声明了着色器版本号,300的意思是代表着色器语言需要是3.0之后的版本。

第二行in vec4 aPos;声明了一个名为aPos的4个分量的输入变量。其中int代表的是定义输入变量,也就是说可以利用这个变量通过CPU向GPU传递数据, 与之对应的是使用out关键字声明的输出变量。注意,int和out是Opengl 3.0之后所做的修改,在Opengl 2.0中与之对应的关键字是attribute和varying,也就是说在Opengl 3中attribute改成了in而varying改成了out。

后面定义的就是一个main函数,这个没什么好解析的,就像所有语言程序一样,作为程序的一个入口,而gl_Position是Opengl中顶点着色器的一个内建输出变量,代表的是最终经过处理后的顶点坐标。

下面我们再来看一个简单的片段着色器的例子:

#version 300 esprecision mediaump float;out vec4 FragColor;void main(){ FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);}

正如顶点着色器那样,片段着色器的第一行也是声明着色器的版本。第二行precision mediaump float;则是声明着色器中浮点变量的默认精度。

C 音视频开发学习资料点击领取音视频开发(资料文档 视频教程 面试题)(FFmpeg WebRTC RTMP RTSP HLS RTP)

在Opengl ES 3的版本中我们需要手动地使用out关键字声明输出着色器的颜色变量,例如上述例子中的第三行,而在Opengl ES2中这不是必须的,因为在Opengl ES2中直接使用内置的变量gl_FragColor即可。 至于为什么这样做,笔者也不得而知..

Opengl ES——着色器(opengles着色器教程)

这里只是通过两个简单的例子让大家对着色器有一个初步的了解,更多关于着色器GLSL的编写规范大家可以参考相关的资料或者书籍进行自我学习,知识繁多,不是三言两语可描述清楚,这里就不再累赘。。。

着色器链接与使用

上面我们对着色器有了一个初步的认识,那么这些着色器小程序如何使用起来呢?

Opengl ES——着色器(opengles着色器教程)

如上图所示,着色器小程序需要通过创建、编译、链接、使用这些重要步骤。这些步骤也没什么好解析的,就像一套规则,大家遵循就是了。

以下是笔者写的一个加载使用着色器的一个工具ShaderUtils.h:

#ifndef NDK_OPENGLES_LEARN_SHADERUTILS_H#define NDK_OPENGLES_LEARN_SHADERUTILS_H#include "GLES3/gl3.h"#include "Log.h"static int loadShaders(int shaderType, const char *code){ // 按照类型,创建着色器 int shader = glCreateShader(shaderType); // 加载着色器代码 glShaderSource(shader, 1, &code, 0); // 编译 glCompileShader(shader); // 检测编译状态 int result = GL_FALSE; glGetShaderiv(shader,GL_COMPILE_STATUS,&result); if(result != GL_TRUE){ GLint infoLen = 0; glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&infoLen); char error[infoLen 1]; // 获取编译错误 glGetShaderInfoLog(shader, sizeof(error) / sizeof(error[0]),&infoLen,error); LOGE("着色器编译失败:%s,%s",error,code); } return shader;}static int createProgram(const char *vertex , const char * fragment){ int vertexShader = loadShaders(GL_VERTEX_SHADER, vertex); int fragmentShader = loadShaders(GL_FRAGMENT_SHADER, fragment); int program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); // 获取一下是否有错误 GLint status = GL_FALSE; glGetProgramiv(program,GL_LINK_STATUS,&status); if(status != GL_TRUE){ GLint infoLen = 0; glGetProgramiv(program,GL_INFO_LOG_LENGTH,&infoLen); char error[infoLen 1]; glGetProgramInfoLog(program,sizeof(error) / sizeof(error[0]) ,&infoLen,error); LOGE("着色器程序链接失败:",error); } // 更严谨一点可通过glValidateProgram()验证着色器程序 // 删除着色器 glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return program;}#endif //NDK_OPENGLES_LEARN_SHADERUTILS_H

关于着色器的介绍就到这里,要想用好着色器,需要在弄懂GLSL语法之后多加实践…

如果你对音视频开发感兴趣,或者对本文的一些阐述有自己的看法,可以在下方的留言框给我留言,一起探讨。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2023年4月29日 上午8:25
下一篇 2023年4月29日 上午8:35

相关推荐

  • 程序项目管理

    程序项目管理:实现高效与质量保障 程序项目管理是现代软件开发中不可或缺的一部分。项目管理者需要协调开发团队,确保项目按时完成,并在质量方面达到要求。本文将介绍程序项目管理的基本原理…

    科研百科 2024年7月16日
    45
  • 崇仁管理系统开发项目

    崇仁管理系统开发项目 随着数字化时代的到来,企业管理系统开发已经成为一种趋势。崇仁管理系统开发项目是一个典型的例子,它展示了企业 how to use technology to …

    科研百科 2025年1月7日
    1
  • 科研项目开课评审

    科研项目开课评审 随着科技的不断进步,科研项目也在不断发展。在科研项目中,开课评审是非常重要的环节,它有助于确保项目的进展和质量,同时也可以帮助研究人员更好地理解项目的目标和内容。…

    科研百科 2025年2月15日
    0
  • 五力并发抓党建(五力并举党建)

    坚持党的领导、加强党的建设是国有企业的“根”和“魂”。近年来,中国航天科工二院北京中天鹏宇科技发展有限公司党委把抓党建强党建作为重大政治责任,探索出“五力并发”抓党建新模式,全方位…

    科研百科 2023年2月27日
    222
  • 埃德加·沙因:组织管理越来越有赖于对亚文化的认识和管理(美国管理学者沙因将组织文化从内容上)

    近十几年,很多公司文化其实只涵盖了有限的核心价值观,组织的实际职能和效能其实是亚文化复合作用的产物。亚文化是什么?亚文化源自两种因素——共同的专业背景、共同的经历。 领导者的核心职…

    2022年6月17日
    312
  • 软件 项目管理 工具

    软件项目管理工具 随着信息技术的不断发展,软件项目管理已经成为了项目管理中不可或缺的一部分。软件项目管理工具可以帮助项目经理更好地管理项目进度,资源,和质量,提高项目的效率和质量。…

    科研百科 2024年5月30日
    65
  • 海康8700综合管理平台

    海康8700综合管理平台:集成化、智能化、高效化 随着信息技术的不断发展,海康威视科技有限公司(He康)的8700综合管理平台也不断升级进化,成为了该公司管理和运营的重要工具。87…

    科研百科 2025年1月4日
    5
  • 如何有效管理员工考勤,考勤排班软件来帮你(考勤系统如何排班)

      许多企业的人力资源部门在选择考勤排班软件时,只是将考勤排班软件作为一种统计工具来选择和购买。考勤最棘手的问题不是制度制定,而是如何激励人性。公司规章制度的设立,其实执行很容易,…

    科研百科 2022年9月24日
    206
  • 降本增效的康复辅具设计:Geomagic Freeform应用演示-马路科技(康复辅具制造)

    康复辅具与3D打印技术 在我国残疾人和老年人群体有着庞大的基数,而他们对于精准医疗和定制化医疗的需求随着科技发展有了更进一步的期望。其中日益成熟的3D打印技术对推动医疗辅具市场发展…

    科研百科 2023年4月15日
    342
  • 周春明的客户关系管理

    周春明的客户关系管理 客户关系管理(CRM)是一种通过收集、分析和利用客户信息,提高客户满意度和忠诚度,促进销售和业务发展的管理方法。在中国,客户关系管理已经成为企业竞争的重要领域…

    科研百科 2024年8月26日
    32