Android OpenGl(二) Shader

[复制链接]
发表于 2025-11-18 11:05:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、Shader

1、什么是Shader,为什么要利用Shder

(1)shader运行在gpu上的小步伐
(2)从前利用固定管线,但缺点是机动度不敷,无法满足复杂需求,为相识决固定管线的缺点,出现了可编程管线,可编程管线允许开发者自界说渲染过程,进步了机动度。
(3)Shader是可编程管线的一部分,用于对各个阶段的自界说,shader可充实利用gpu并行盘算本领,进步渲染速率,Shader可通过编程对gpu机动控制。
2、两种Shader


  • Vertex Shader–顶点Shader,用于处理处罚3D多少图形的顶点。
  • Fragment Shader–片元Shader,用于处理处罚像素颜色和纹理
3、Shader的输入与输出


  • 吸取顶点数据,输出构造好的三角形
  • 吸取片元数据,为每个像素设置差别的颜色
4、最根本的图形–三角形


  • 图形学中,三角形是最根本的图形
  • 全部复杂图形都是由三角形构成的
  • 三角形是由顶点和片元构成的
二、标准坐标系与屏幕坐标系

1、标准装备坐标系


  • 屏幕中心是(0,0)
  • x,y的范围在[-1,1]之间
  • 是shader的输出坐标系

2、屏幕坐标系


  • 屏幕左上角是(0,0)
  • 屏幕右下角是(width,height)
  • 屏幕坐标系的单位是像素
  • OpenGL会自动将标准装备坐标转成屏幕坐标系。

3、应用在什么地方?


  • 标准装备坐标系是Shader的输出
  • 屏幕坐标系用于模子的终极表现
4、标准装备坐标系到屏幕坐标系


  • 先将标准坐标系中的顶点+1
  • 每个顶点成衣屏幕的宽/高
  • 也可以通过一个变更矩阵直接完成两步操纵。
三、着色器Shader作用及语法

1、GLSL(Graphics Language Shader Language )根本语法


  • 语法类似于C语言
  • 支持向量、矩阵等数学运算
  1.   "attribute vec4 vPosition;" +
  2.   "void main() { " +
  3.   "   gl_Position = vPosition;" +
  4.    "}"
复制代码
2、数据的通报


(1)一个opengl步伐包罗了2个shader,一个是vertex shader(用于处理处罚顶点),一个是Fragment shader(用于处理处罚像素)。
(2)可以将opengl shader比喻成一个芯片,每个芯片都有许多引脚,每个引脚都有唯一的id,比如上图引脚id1,引脚1关联是vertex shader 的vPosition,引脚2 关联的是fragment shader的vColor.
(3)当我们将数据通报给引脚1的时间,会自动通报给vPosition,同理fragment shader 会自动通报给vColor。
(4)怎样将数据传送给引脚(差别范例数据方法差别):
以vPosition为例:第一步:如图调用opengl提供的api的glGetAttribLocation 来获取到vPosition变量对应的引脚。第二步:拿到引脚ID之后,调用glEnableVertexattribArrray()使得引脚处于开启状态,第三步调用glVertexAttribPointer(ID,…,vertexData),将准备好的vertex data当做输入参数传入api中,终极传给vPosition。如许vertextShader就可以通过vPosition得到数据。
以vColor为例:由于vColor是uniform范例的变量,它只须要2步,起首是glGetUniformLocation来获取引脚位置,第二步通过glUniform4fv()将数据通报给内部vColor。

vertex shader 重要有上图几种变量范例,attribute 范例、uniforms范例、Samplers范例变量(一种uniforms的特别范例,重要用于纹理绘制),

3、怎样创建、编译和利用Shader步伐
  1.     /**
  2.      * 创建shader,加载shader程序
  3.      */
  4.     private fun loadShader(type: Int, shaderCode: String): Int {
  5.         val shader = GLES20.glCreateShader(type)
  6.         GLES20.glShaderSource(shader, shaderCode)
  7.         GLES20.glCompileShader(shader)
  8.         return shader
  9.     }
  10.    private fun linkProgram(vertexShader: Int, fragmentShader: Int) {
  11.         // 创建空的opengl es 程序
  12.         program = GLES20.glCreateProgram()
  13.         program?.let {
  14.             // 将顶点着色器加入程序
  15.             GLES20.glAttachShader(it, vertexShader)
  16.             // 将片元着色器加入程序
  17.             GLES20.glAttachShader(it, fragmentShader)
  18.             // 链接到着色器程序
  19.             GLES20.glLinkProgram(it)
  20.             // 将程序加入到opengl30环境中
  21.             GLES20.glUseProgram(it)
  22.             val info = GLES20.glGetProgramInfoLog(it)
  23.             // 打印链接程序日志日志
  24.             Log.e("wdf", "info==" + info)
  25.         }
  26.     }
复制代码
利用
  1.      // 创建定点着色程序
  2.         val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
  3.         // 创建片元着色程序
  4.         val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
  5.        linkProgram(vertexShader, fragmentShader)
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表