在浏览器页面中运行程序,需要通过WebGL,借助JavaScript向GPU发送绘制命令
假设你拥有一个神奇的"magic_gpu" 对象,要用它在屏幕上画一个红色三角形。请用伪代码写下你认为需要的步骤。
思考方向:
所有现代图形API(OpenGL, WebGL, Vulkan...)都遵循一个相似的模型。
OpenGL是按面向过程的设计,因此对于一些逻辑函数,往往有多种实现,其区别在于不同的类型,如往着色器中传输数值
其底层的数据存在模式也同样,因此需要格外关注数据类型及其占用空间大小
特性 | WebGL | 原生 OpenGL |
---|---|---|
核心思想 | 完全一致 (可编程管线, 着色器, 缓冲) | |
编程语言 | JavaScript | C / C++ |
运行平台 | 浏览器 | 操作系统原生 |
环境配置 | 零配置 | 复杂 (库, 驱动, 窗口) |
基于标准 | OpenGL ES (嵌入式版) | 完整版 OpenGL |
WebGL函数定义
GLSL,全称为OpenGL Shading Language,是一种与C风格类似的编程语言,提供了预定义的矩阵、向量(2,3,4d)等类型,支持操作符重载,具有C++风格的构造器。与GLSL类似的编程语言还有NVidia的Cg和微软的HLSL。源代码需要送到着色器中编译运行。WebGL中定义的函数其编译、链接运行都在着色器中,可以直接实现对着色器中数据的控制
最早的着色器编程语言类似汇编风格,OpenGL通过扩展添加对顶点着色器和面片着色器的函数支持,主要的着色器编程语言有两种:
GLSL中没有定义指针,所有的变量在传递时都按值传递,建立变量的本地副本。并且,因为向量和矩阵都是基本数据类型,可以直接在GLSL函数中作为输入输出使用,如mat3 func(mat3 a)
mat4 a;
vec4 b, c, d;
c=b*a; // a column vector stored as a 1d array
d=a*b; // a row vector stored as a 1d array
vec4 a, b;
a.yz=vec2(1.0, 2.0, 3.0, 4.0);
b=a.yxzw;
面片光照计算
纹理映射
将着色器程序与应用程序进行连接,需要以下步骤:
多边形,可定义以下三种属性:
关于WebGL渲染
从概念上讲,测试多边形是否是简单多边形,是否是凸多边形虽然简单,实际实现却很耗时,因此在现在的版本实现中只保留了渲染三角形,而将多边形划分成三角形的工作交由用户完成
待三角化四边形
"坏"三角化
"好"三角化
凸多边形三角化,从abc开始,拿掉b,加上acd,拿掉c,加上ade......
非凸多边形
非凸多边形分割,从最左边的点开始
属性决定了物体的外观,包括如下几点:
以上属性在OpenGL中能够得到完整支持,但是在WebGL中只有少部分支持,如
每种颜色分量在帧缓存中都是独立存储,每种颜色各占8位,颜色值用0.0到1.0之间的浮点数表示,对应于非负整型的0到255
颜色通过索引表查找得到,一般用8位索引,适用于内存空间较少的情况,能够表示的颜色较少,无法满足阴影绘制的需要,现在已较少采用
颜色平滑处理默认采用平滑着色(Smooth shading),在光栅化阶段,在可见的多边形上对顶点颜色进行插值
另一种为平面着色(Flat shading),多边形的颜色由第一个顶点的颜色决定,并在着色器中处理
颜色是在面片着色器中设置,但其值可以由应用程序或是任一着色器设定
在应用程序中设定颜色,需将颜色值作为常量传递给顶点着色器或作为顶点属性进行传递
在顶点着色器中设定,需将其值作为变量传递给面片着色器
在面片着色器中设定,可通过代码修改