OpenGL ES应用开发实践指南(android 卷)笔记 第二章2

第二章:定义顶点和着色器 2

1. OpenGL管道概述:读取顶点数据-->执行顶点着色器-->组装图元-->光栅化图元-->执行片段着色器-->写入帧缓冲区-->显示在屏幕上。


attribute vec4 a_Position;

void main(){
    gl_Position = a_Position;
}

2.这些着色器使用GLSL定义,GLSL是OpenGL的着色语言;这个着色语言的语法结构与C语言相似。更多的信息可以参考前文提到的快速参考卡片或者完整的规范。https://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf

3.对于我们定义过的每个单一的顶点,顶点着色器都会被调用一次;当它被调用的时候,它会在a_Position属性里接收当前顶点的位置,这个属性被定义为vec4类型。

4.一个vec4是包含4个分量的向量;在位置的上下文中,可以认为这4个分量是x,y,z和w坐标,x,y,z对应一个三维位置,而w是一个特殊的坐标。默认情况下,OpenGL都是把向量的前三个坐标设为0,并把最后一个坐标设为1。

5.还记得曾经讲过一个顶点会有几个属性,比如颜色和位置。关键词『attribute』就是把这些属性放进着色器的手段。

之后,可以定义main(),这是着色器的主要入口点;它所做的就是把前面定义过的位置复制到指定的输出变量gl_Position;这个着色器一定要给gl_Position赋值;OpenGL会把gl_Position中存储的值作为当前顶点的最终位置,并把这些顶点组装成点、直线和三角形。

6.创建第一个片段着色器

既然已经创建了一个顶点着色器,就有了为每个顶点生成最终位置的子例程;我们仍然需要创建一个为每个片段生成最终颜色的子例程。在此之前,让我们花些时间了解一下什么是片段,以及一个片段是怎么产生的。

光栅化(Rasterization)技术

移动设备的显示屏由成千上万个小的、独立的部件组成,它们成为像素(pixel);这些像素中的每一个都有能力显示几百万种不同颜色范围中的一种颜色。然而,这实际上是一种视觉技巧:大多数显示器并不能真正创造几百万种颜色,所以每个像素通常由三个单独的子组件构成,它们发出红色、绿色和蓝色的光,因为每个像素都非常小,人的眼睛会把红色、绿色及蓝色的光混合在一起,从而创造出巨量的颜色范围;把足够多的单独的像素放在一起,就能显示出一页文本或者蒙娜丽莎像。

OpenGL通过『光栅化』的过程把每个点、直线及三角形分解成大量的小片段,它们可以映射到移动设备显示屏的像素上,从而生成一幅图像。这些片段类似于显示屏上的像素,每一个都包含单一的纯色。为了表达颜色,每个片段都有4个分量:其中红色、绿色、蓝色用来表示颜色,阿尔法(alpha)分量用于表示透明度。

7.显示系统通常会把这些片段直接映射到屏幕上的像素,结果几个片段就对应一个像素;人呢人,并不总是这样的:一个超高分辨率的设备可能需要使用较大的片段,以减少GPU的工作负荷。

precision mediump float;
uniform vec4 u_Color;

void main(){
       gl_FragColor = u_Color;
}
片段着色器的主要目的就是告诉GPU每个片段的最终颜色应该是什么。对于基本图元的每个片段,片段着色器都会被调用一次,因此,如果一个三角形被映射到10000个片段,片段着色器就会被调用10000次。

8.精度限定符

在这个片段着色器中,文件顶部的第一行代码定义了所有浮点数据类型的默认精度。这就像在Java代码中选择浮点数还是双精度浮点数一样。可以选择lowp、mediump和highp,它们分别对应低精度、中等精度及高精度;然而,只有某些硬件实现支持在片段着色器中使用highp。

为什么顶点着色器没有定义精度呢?顶点着色器同样可以改变其默认的精度,但是对于一个顶点的位置而言,精确度是最重要的,OpenGL设计者决定把顶点着色器的精度默认设置成最高级:highp。

你可能已经猜到了,高精度数据类型更加准确,但是这是以降低性能为代价的;对于片段着色器,出于最大兼容性的考虑,选择了mediump,这是基于速度和质量的权衡。

9.生成片段的颜色

这个片段着色器的剩余部分与早前定义的顶点着色器一样。不过这次我们要传递一个uniform,它叫u_Color。它不像属性,每个顶点都要设置一个;一个uniform会让每个顶点都使用同一个值,除非我们再次改变它。如顶点着色器中的位置所使用的属性一样,u_Color也是一个四分量向量,但在颜色的上下文中,这四个分量分别对应红色、绿色、蓝色和阿尔法。

接着我们定义了main(),它是这个着色器的主入口点,它把我们在uniform里定义的颜色复制到那个特殊的输出变量——gl_FragColor。着色器一定要给gl_GragColor赋值,OpenGL会使用这个颜色作为当前片段的最终颜色。


10.OpenGL颜色模型

OpenGL使用累加RGB颜色模型,它只用了三种基本颜色:红色、绿色、蓝色。许多颜色都是通过把这三种基本颜色按不同比例混合在一起而创造的。例如,红色和绿色放在一起会生成黄色,红色和蓝色放在一起可以产生品红色,而蓝色和绿色放在一起就会创造出青色,把红色、绿色和蓝色放在一起,就能看见白色。

这个模型的工作原理与你可能在学校里学过的减色绘画模型(subtractive paint model)不同:在减色绘画模型里,加入蓝色和黄色制作出绿色,而加入很多颜色会产生黑棕色或者黑色。这是因为颜料不发光,而是吸收光;画上使用的颜色越多,光被吸收得越多,这幅画就会表现得越暗。

累加RGB模型遵循光本身的属性,当两柱不同颜色的光线混合在一起时,不会看见更暗的颜色,而是更亮的颜色。一场大雨过后,当我们观察天空中的彩虹时,我们实际上看到了可见光光谱中所有不同的颜色,他们可以合并成白色。

11.OpenGL假定这些颜色互相之间是线性关系:一个值为0.5的红色,其亮度是值为0.25的红色的两倍;而一个值为1的红色的亮度是值为0.5的红色的两倍。这些基本的颜色值被限定在范围【0,1】内,0代表缺少这个特定的基本颜色,而1代表那么颜色的最大强度。

这个颜色模型很好地映射到移动设备使用的显示屏和计算机屏幕上(然而,在13.3.3节中,我们会知道这个映射并不是真的一对一)。这些显示设备几乎总是使用这三种基本颜色:红色、绿色和蓝色(为了有『更纯的黄色』,有些设备可能用黄色作为另外一个基本颜色),0映射到一个未点亮的像素分量,而1映射到那个颜色的全亮度。使用这个颜色模型,人眼能看到的所有颜色几乎都可以被OpenGL渲染出来,并显示在屏幕上。

在第4章里,我们会学习更多关于颜色使用的内容。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值