在webgl中,调用了OpenGL-ES-2.0的API,而在OpenGL-ES专为嵌入式设备设计,其和其它设备一样,都是使用GLSL(GL Shading Language)来编写片段程序并执行于GPU的着色器上,来完成对对象的渲染。GLSL在其中起着相当重要的作用,所以要玩好webgl,我们就得把GLSL搞懂,本文主要介绍shader的基础使用及组成。

整个管线处理过程:

1.指定几何对象

  • 顶点数组(直接将顶点数据传送至shader里)
  • 顶点索引(将顶点数据保存于缓冲区中,用索引来从缓冲区获取数据传入shader)

2.逐个顶点操作

3.图元组装

  根据指定的图元组装方式将若干顶点组成一个图元,OpenGL支持的几何图元有点、线、不闭合折线、闭合折线、多边形、三角形、线型连续填充三角形、扇形连续填充三角形、四边形以及连续填充四边形。

  而webgl支持的图元为POINTS(点), LINE_STRIP(不闭合折线), LINE_LOOP(闭合折线), LINES(独立的线段), TRIANGLE_STRIP(顶点按顺序相连的三角形), TRIANGLE_FAN(扇形顺序组合三角形), TRIANGLES(每三个顶点组合成一个三角形)。

  绘制三角形序列的三种方式解释了三种三角形绘制方法之间的不同。

4.图元处理

5.栅格化(生成片元fragment)

6.片元处理

7.逐个片元操作

8.帧缓冲区操作

在这八个步骤中,我们最重要的是对顶点和片元的操作,在整个管线中,我们可以加入的自己程序的部分则是顶点着色器和片元着色器部分。

着色器


顶点着色器:

  操作的是顶点值和其关联的数据,它可完成下面这些操作:

  • 顶点变换
  • 法线变换以及规格化
  • 纹理坐标生成
  • 纹理坐标变换
  • 光照
  • 彩色材质应用

  顶点着色器必须计算坐标在裁剪空间中的齐次位置并将结果存储在特殊的输出变量gl_Position中,它还有特殊的输出变量gl_ClipVertex,gl_PointSize。

  顶点处理器的输出将被发送到后续的处理阶段,即:图元组装,用户裁剪,平截裁剪,透视划分,视口贴图,多边形偏移,多边形模式,阴影模式,消隐等。

片元着色器:

  处理片元值及其相关联数据,它可执行传统的图形操作,如:

在插值等到的值上的操作

  • 访问纹理
  • 应用纹理
  • 雾化
  • 颜色汇总

  片元着色器其有特殊的输入变量gl_FragCoord(片元的窗口相对坐标)和gl_FrontFacing(正面图元为true,反之为false),经过计算颜色和深度将这些值写入特殊的输出变量gl_FragColor和gl_FragDepth中,或者完全丢弃(使用discard关键字)片元。

  片元处理器的一大优点是它可以任意多次地访问纹理内存,并可以任意方式结合所读取的值,一次纹理访问的结果可作为执行另一次纹理访问的基础。

有三个精度可选择:lowp highp mediump

精度可指定于变量或设置默认精度

顶点着色器中的float和init默认精度为highp

片元着色器中float没有默认精度,所以必须为其指定默认精度,如:precision mediump float;

着色器多个执行是可并行发生的,针对每个顶点都会执行一次顶点着色器,针对每个片元都会执行一次片元着色器。

限定符


我们要向着色器中传入数据,则要了解其里面变量的组成和输入方式

属性变量(attribute):

  这些变量代表了非常频繁地从应用程序传递到顶点处理器的值,只应用于程序中定义顶点数据,所以只允许作为顶点着色器的一部分,该值可以像每个顶点那样经常变动

一致变量(uniform):

  用来将数据值从应用程序传递到顶点处理器或片元处理器,一致变量通常用来提供不频繁变动的值。

易变变量(varying):

  定义了从顶点处理器传递到片元处理器的数据。

常量变量(const):

  如C中的常量变量

数据类型


标量:

  支持使用浮点数(float)、整数(int)和布尔值(bool)

矢量:

  浮点数矢量:

    vec2  (2个浮点数的矢量)

    vec3  (3个浮点数的矢量)

    vec4  (4个浮点数的矢量)

  整数矢量:

    ivec2  (2个整数的矢量)

    ivec3  (3个整数的矢量)

    ivec4  (4个整数的矢量)

  布尔矢量:

    bvec2  (2个布尔值的矢量)

    bvec3  (3个布尔值的矢量)

    bvec4  (4个布尔值的矢量)

矩阵:

  mat2  (2×2的浮点数矩阵)

  mat3  (3×3的浮点数矩阵)

  mat4  (4×4的浮点数矩阵)

  mat矩阵就像是一个vec数组,它也可以使用数组来进行访问。

取样器:

  sampler1D  (访问一个一维纹理)

  sampler2D  (访问一个二维纹理)

  sampler3D  (访问一个三维纹理)

  samplerCube  (访问一个立方贴图纹理)

  sampler1DShadow  (访问一个带对比的一维深度纹理)

  sampler2DShadow  (访问一个带对比的二维深度纹理)

  只能通过uniform限定的取样器从应用程序接收取样器

  使用时:  uniform sampler2D texture;

操作


如果要对矢量进行部分操作,则可用访问矢量中的部分来使用,在shader中,共有三组组合供使用:

  •   x  y  z  w
  •   s  t  p  q
  •   r  g  b  a

这四个值只是分别读取矢量中的第一个、第二个、第三个、第四个值,只是为了编写方便,语义化了三组组合,分别为坐标、纹理、颜色,但是使用它们去读取出来的值是一样的,如:

vec4 values = vec4(1.0,2.0,3.0,4.0);
values.z; //3.0
values.p; //3.0
values.b; //3.0
values[2]; //3.0

这三组使用时必须成组出现,不能混组出现,如:

vec4 values = vec4(1.0,2.0,3.0,4.0);
vec2 combination1 = values.xy;    //同一组,正确
vec3 combination2 = values.rgb; //同一组,正确
vec3 combination3 = values.xt;   //不同组,不正确

对矩阵的读取可以像数组一样:

vec2 x,y;
mat2 matrix;
x = matrix[];
y = matrix[];

运算


对于矢量的计算:

vec3 v,u,w;
w = v + u; //计算过程等价于 w.x = v.x + u.x;
w.y = v.y + u.y;
w.z = v.z + w.z;

对于矩阵和矢量的计算:

//该过程遵守线性代数中的计算规定,即做点乘的两个矩阵,前一个矩阵的行数等于后一个矩阵的列数

vec4 v,u;
mat4 m;
v * m; //行矢量与矩阵相乘
m * v; //矩阵与列矢量相乘
m * m; //矩阵与矩阵相乘

运算顺序:

//当多个矩阵同时施加加顶点矢量上时,则要以相反的顺序矩阵相乘
//如想实现先Ma再Mb的运算 vec4 v,u;
mat4 Ma,Mb; u = Mb * (Ma * v);
//即
u = (Mb * Ma) * v;
//即
u = Mb * Ma * v;

与C和C++差异

着色语言作为一种处理数字的语言,而不是处理字符或字符串数据的语言,在其中没有包含对指针、字符串、字符或基于这些类型的任何操作支持。

并且为了使编译器和图形硬件的实现负担更小,该语言不支持双精度浮点数、字节、短整数、长整数或者这些类型的无符号变化形式。

其包括了C++的一些重要语言特性:支持函数重载,支持基本类型bool。

注:

在向顶点着色器中进行传值时,顶点着色器会从缓存中依次读取每个顶点,如果使用的是顶点数组方法:

如传入:new Float32Array([1.0,1.0,1.0,0.0,

              0.5,0.5,0.5,0.0]);

那么在shader中,假设有attribute vec4 position;

会从缓存中依次读取四个数来作为position进行处理,则总共执行了两次顶点着色器,共两个顶点。

如果在shader中有attribute vec2 position;

则会从缓存中依次读取两个数来作为position进行处理,共四个顶点,顶点着色器执行四次。

附:

WebGL-1.0参考卡片:http://files.cnblogs.com/files/zhiyishou/webgl-reference-card-1_0.pdf

OpenGL-ES-2.0参考卡片:http://files.cnblogs.com/files/zhiyishou/OpenGL-ES-2_0-Reference-card.pdf

The end.

WebGL中的OpenGL着色器语言的更多相关文章

  1. unity中使用的着色器语言

    在unity中,着色器编程使用了一列列的HLSL语言变种(也叫作Cg,但是大部分实际上两者都是一样的). 目前,为了在不同平台下保持最好的跨平台性, 取样贴图时,最好使用DX9风格 的HLSL. 着色 ...

  2. OpenGL官方教程——着色器语言概述

    OpenGL官方教程——着色器语言概述 OpenGL官方教程——着色器语言概述 可编程图形硬件管线(流水线) 可编程顶点处理器 可编程几何处理器 可编程片元处理器 语言 可编程图形硬件管线(流水线) ...

  3. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  4. OpenGL ES着色器语言之操作数(官方文档第五章)

    OpenGL ES着色器语言之操作数(官方文档第五章) 5.1操作数 OpenGL ES着色器语言包含如下操作符. 5.2数组下标 数组元素通过数组下标操作符([ ])进行访问.这是操作数组的唯一操作 ...

  5. OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)

    OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,unifo ...

  6. OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围

    OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)   所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符. ...

  7. OpenGL ES着色器语言之静态使用(static use)和预处理

    OpenGL ES着色器语言之静态使用(static use) 在OpenGL ES中有一个术语叫静态使用(static use),什么叫静态使用呢? 在写代码中,对于一个变量可能具有以下三种情况: ...

  8. OpenGL ES着色器语言之着色概览(官方文档)

    OpenGL ES着色器语言之着色概览(官方文档第二章) 事实上,OpenGL ES着色语言是两种紧密关联的语言.这些语言用来在OpenGL ES处理管线的可编程处理器创建着色器. 在本文档中,除非另 ...

  9. Android OpenGL ES 开发(八): OpenGL ES 着色器语言GLSL

    前面的文章主要是整理的Android 官方文档对OpenGL ES支持的介绍.通过之前的文章,我们基本上可以完成的基本的形状的绘制. 这是本人做的整理笔记: https://github.com/re ...

随机推荐

  1. CentOS 6上的redis搭建实战记录(转)

    redis 是一个基于内存的高性能key-value数据库,数据都保存在内存中定期刷新到磁盘,以极高的读写效率而备受关注.他的特点是支持各种数据结构,stirng,hashes, list,set,和 ...

  2. Thrift实现C#调用Java开发步骤详解

    概述 Thrift实现C#调用Java开发步骤详解 详细 代码下载:http://www.demodashi.com/demo/10946.html Apache Thrift 是 Facebook ...

  3. 基于Redis的消息队列php-resque

    转载:http://netstu.5iunix.net/archives/201305-835/ 最近的做一个短信群发的项目,需要用到消息队列.因此开始了我对消息队列选型的漫长路. 为什么选型会纠结呢 ...

  4. operator new 和 operator delete 实现一个简单内存泄漏跟踪器

    先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针.当前文件.当前行等信息添加进Trace 成员map容器内,在调用operator delete ...

  5. C# BackgroundWorker的Bug???

    废话不多说,上代码: public partial class Form1 : Form { BackgroundWorker _bgWorker; int count; public Form1() ...

  6. 如何利用webmin在Linux主机中添加网站

    Linux系统因其高效稳定而受到广大用户的推崇与青睐,然后其管理的复杂性也使很多用户望而却步,动弹不得.为了降低 Linux系统的管理难度,更有效方便的使用该系统,我司所有Linux主机或VPS系统均 ...

  7. Spring Cloud概述

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  8. Decoration5:引入Actuator进行站点监控

    1.添加依赖 2.重启应用 3.下图显示了一些默认的监控端点 这是数据可以在前台用来做饼图和柱状图什么的,不过实际上我们现在还用不到,于是就不深入研究

  9. 【Android】15.1 后台任务和前台任务

    分类:C#.Android.VS2015: 创建日期:2016-02-29 一.简介 Android的活动(Activities)可以有多种状态,具体取决于用户的行为以及对操作系统的要求.虽然Acti ...

  10. Linux进程间通信的几种方式总结--linux内核剖析(七)

    进程间通信概述 进程通信的目的 传输数据 一个进程须要将它的数据发送给还有一个进程.发送的数据量在一个字节到几M字节之间 共享数据 多个进程想要操作共享数据,一个进程对共享数据 通知事 一个进程须要向 ...