图形图像世界

OpenGL ES 的架构图

计算机图形学的发展并不存在标准的编程模型,开发商们都仅提供自家的硬件底层接口。个人和组织开发特定的屏幕显示内容,然而在高效性和可移值性均存在问题。在最初的群魔乱舞的情况下,使得我们有了更高的需求,最后图形引擎的步伐加快同时在计算机世界形成了一套图形API---OpenGL。

  • openGL的从现实物理学,特别现代的光学成像系统角度来进行深度思考。
  • openGL完成了从想象到计算机视图的过程,之间经过多种变换过程。

光学成像系统

对于同一个世界的物体,其最终经过成像系统生成具体的图像特征需要一套完成的成像系统。

  1. 对象:轮廓,材质,颜色等
  2. 观察者: 眼睛,照相机等数字化设备
  3. 外部条件:光源,天气情况

图像的确定依赖观察者,因此虚拟的成像系统中必须有对象与观察者、外部条件的关联方法。在成像模型中,可以进行几何变换(小孔成像)等,并不是所有的物体最终都能完整的在胶片中成像(进行窗口移动裁剪),给定投影位置和裁剪窗口大小,便能确定可以出现的图像。

OpenGL的实现

计算机图形学考虑人造对象的概念,模拟我们的现实生活环境,人们通过,点,线,多边形来构造对象。其流程大概如下:
首先构想我们需要显示的对象模型,然后根据宏观世界中的表现形态转换成以我们的眼睛为观察者的显示,通过成像系统的投影,根据显示设备的大小进行一定的裁剪处理,适应不同的计算机不同的窗口显示,最终形成我们在计算机设备上的构想对象的缩影。
而其中经历的变换过程,OpenGL管线 中对应一套处理过程,上图主要是对于移动嵌入设备的流程。


---建模函数--->模型空间(模型坐标)--建模转换--->世界空间(世界坐标系)--视见转换->眼睛空间(眼坐标)---投影变换--->剪彩空间(标准化设备坐标)---视口变换--->屏幕坐标


可能有些⼈会认为,为何要经过⼀一个世界坐标。为何不直接对模型坐标进⾏投影,⽣成图像那不也是可以的吗,为什么需要世界坐标的存在?

当程序有上百个单独的对象的时候,你要对这个复杂模型进⾏⼀次性的建模基本是不可能的,你的坐标系怎么取也⽆无法兼顾到能完美的构建每⼀个物体,所以你必须为每⼀件物体进⾏行单独建模。那么这样问题就来了,这么多的对象。如果不通过⼀个中间体统一的话,怎么直接进行大量工作的处理。

编程实现GLSL

大家都知道 2.0是从1.0的固定管线引入图像编程机制,包括顶点着色器,片元着色器以及GLSL语言,增加了可编程管线满足开发需求和呈现能力和渲染性能(顶点缓冲区对象减少CPU和显卡之间的交互VBO。。。)可编程的脚本语言GLSL(Shader Language)实现以嵌入式 OpenGL-ES 2.0 ios中的为例:

简单的顶点着色器和片元着色器脚本(没有对应使用):

uniform mat4 Projection; 
uniform mat4 ModelView;
attribute vec4 Position;
varying vec4 DestinationColor; 
attribute vec4 SourceColor;
void main(void) 
{
   gl_Position = (Projection * (ModelView * Position));
   DestinationColor =SourceColor;
}
precision mediump float;
varying vec4 DestinationColor; 
void main()
{
  gl_FragColor = DestinationColor;
}

顾名思义,顶点着色器和片元着色器处理流程对应上图,主要进行顶点变换,颜色输出,GLSL语法很简单,易上手想要改变世界的可以上手操作了。

对应OpenGL成像的流程,openGL-ES结构图详解:

Vertex Array/Buffer objects:顶点数据来源,这时渲染管线的顶点输入,通常使用 Buffer objects效率更好。

Vertex Shader:顶点着色器通过可编程的方式实现对顶点的操作,如进行坐标空间转换,计算法线,顶点颜色以及纹理坐标;

Primitive Assembly:图元装配,经过着色器处理之后的顶点在图片装配阶段被装配为基本图元。OpenGL ES支持三种基本图元:点,线和三角形,它们是可被 OpenGL ES 渲染的。接着对装配好的图元进行裁剪(clip):保留完全在视锥体中的图元,丢弃完全不在视锥体中的图元,对一半在一半不在的图元进行裁剪;接着再对在视锥体中的图元进行剔除处理(cull):这个过程可编码来决定是剔除正面,背面还是全部剔除。

Rasterization:光栅化。在光栅化阶段,基本图元被转换为二维的片元(fragment),fragment 表示可以被渲染到屏幕上的像素,它包含位置,颜色,纹理坐标等信息,这些值是由图元的顶点信息进行插值计算得到的。这些片元接着被送到片元着色器中处理。

*光栅化是 顶点着色器到片元着色器的过渡即脚本中的 输出和输入。

Fragment Shader:片元着色器通过可编程的方式实现对片元的操作。在这一阶段它接受光栅化处理之后的fragment,color,深度值,模版值作为输入。

Per-Fragment Operation:在这一阶段对片元着色器输出的每一个片元进行一系列测试与处理,从而决定最终用于渲染的像素。(像素检测,剪裁测试,模板测试,深度测试,混合等)

*混合是将片段的颜色和帧缓冲区中已有的颜色值进行混合,并将混合所得的新值写入帧缓冲,其中包含各种混合模式。

Framebuffer:存储这可以用于渲染到屏幕或纹理中的像素值,也可以从中读回像素值,可以进行一些即时操作效果的处理。


"程序员三大浪漫 : 操作系统 编译原理 图形学"

暂不争论上述描述,图像学单独一门学科,一篇文章不能够将现实世界到计算机世界图像处理显示过程描述完整,欢迎大家指正。

你可能感兴趣的:(图形图像世界)