什么是GPU?
GPU:Graphic Processing Unit,中文翻译为“图形处理器”。显卡包括(GPU,显存,显卡BIOS,显卡PCB板)。
什么是Shader?
Shader程序:GPU执行的,针对3D对象进行操作的程序。
 
Shader有哪几种?
CG:与DirectX 9.0以上以及OpenGL 完全兼容。运行时或事先编译成GPU汇编代码。
HLSL: 主要用于Direct3D。平台:windows。
GLSL: 主要用于OpenGL。  平台:移动平台(iOS,安卓),mac(only use when you target Mac OS X or OpenGL ES 2.0)
 
 
 
 

顶点着色器是一个可编程的处理单元,执行顶点变换、纹理坐标变换、光照、材质等顶点的相关操作,每顶点执行一次。替代了传统渲染管线中顶点变换、光照以及纹理坐标的处理,开发人员可以根据自己的需求自行开发,大大增加了程序的灵活性。

顶点着色器主要是传入相应的Attribute变量、Uniforms变量、采样器以及临时变量,经过顶点着色器后生成Varying变量。如下图所示:

shader 的基本用法

                                               

(1)attribute变量(属性变量)只能用于顶点着色器中,不能用于片元着色器。 一般用该变量来表示一些顶点数据,如:顶点坐标、纹理坐标、颜色等。

(2)uniforms变量(一致变量)用来将数据值从应用程其序传递到顶点着色器或者片元着色器。 该变量有点类似C语言中的常量(const),即该变量的值不能被shader程序修改。一般用该变量表示变换矩阵、光照参数、纹理采样器等。

(3)varying变量(易变变量)是从顶点着色器传递到片元着色器的数据变量。顶点着色器可以使用易变变量来传递需要插值的颜色、法向量、纹理坐标等任意值。 在顶点与片元shader程序间传递数据是很容易的,一般在顶点shader中修改varying变量值,然后片元shader中使用该值,当然,该变量在顶点及片元这两段shader程序中声明必须是一致的 。例如:上面代码中应用程序中由顶点着色器传入片元着色器中的vColor变量。

(4)gl_Position 为内建变量,表示变换后点的空间位置。 顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后,生成新的顶点位置。新的顶点位置通过在顶点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理

 

片元着色器介绍

片元着色器是一个处理片元值及其相关联数据的可编程单元,片元着色器可执行纹理的访问、颜色的汇总、雾化等操作,每片元执行一次。片元着色器替代了纹理、颜色求和、雾以及Alpha测试,这一部分是需要开发者自己开发的。

(1)varying指的是从顶点着色器传递到片元着色器的数据变量

(2)gl_FragColor为内置变量,用来保存片元着色器计算完成的片元颜色值,此颜色值将送入渲染管线的后继阶段进行处理。

       二、加载着色器代码示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

private int loadShader( int shaderType, String source)

{

  // 创建一个新shader

  int shader = GLES20.glCreateShader(shaderType);

  // 若创建成功则加载shader

  if (shader != 0)

  {

    // 加载shader源代码

    GLES20.glShaderSource(shader, source);

    // 编译shader

    GLES20.glCompileShader(shader);

    // 存放编译成功shader数量的数组

    int[] compiled = new int[1];

    // 获取Shader的编译情况

    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);

    if (compiled[0] == 0)

    {

      //若编译失败则显示错误日志并删除此shader

      Log.e(TAG, "Could not compile shader " + shaderType + ":");

      Log.e(TAG, GLES20.glGetShaderInfoLog(shader));

      GLES20.glDeleteShader(shader);

      shader = 0;

    }

  }

 

  return shader;

}

上述示例代码中主要用到了三个方法:

GLES20.glCreateShader(shaderType);
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);

1. GLES20.glCreateShader(), 创建一个容纳shader的容器,称为shader容器。

1

2

3

4

5

函数原型:

int glCreateShader (int type)

方法参数:

GLES20.GL_VERTEX_SHADER          (顶点shader)

GLES20.GL_FRAGMENT_SHADER        (片元shader)

       如果调用成功的话,函数将返回一个整形的正整数作为shader容器的id。 如果对c++熟悉的话,该函数的返回值理解为指针或者句柄更合适。

2. GLES20.glShaderSource(shader, source),添加shader的源代码。源代码应该以字符串数组的形式表示。当然,也可以只用一个字符串来包含所有的源代码。

1

2

3

4

5

函数原型:

void glShaderSource (int shader, String string)

参数含义:

shader是代表shader容器的id(由glCreateShader返回的整形数);

string是包含源程序的字符串数组。

3. GLES20.glCompileShader(shader),对shader容器中的源代码进行编译。

1

2

3

4

函数原型:

void glCompileShader (int shader)

参数含义:

shader是代表shader容器的id。

相关文章: