【OPENGL】第三篇 着色器基础(一)

 


 

在这一章,咱们会学习什么是着色器(Shader),什么是着色器语言(OpenGL Shading Language-GLSL),以及着色器怎么和OpenGL程序交互。html

 


 

首先咱们先来看看什么叫着色器。编程

Shader(着色器)是用来实现图像渲染的,用来替代固定渲染管线的可编程程序。缓存

着色器替代了传统的固定渲染管线,能够实现3D图形学计算中的相关计算,因为其可编程性,能够实现各类各样的图像效果而不用受显卡的固定渲染管线限制。这极大的提升了图像的画质。框架

在上一篇文章( http://www.cnblogs.com/MyGameAndYOU/p/4681710.html )编程语言

关于OpenGL的第一个例子中,咱们已经接触过顶点着色器(Vertex Shader)以及片断着色器(Fragment Shader)的相关代码。另外,有些书籍或者文章也将片断着色器称为像素着色器(Pixel Shader)函数

 

话说回来,在咱们了解着色器以前,让咱们先了解固定渲染管线(fixed-function pipeline)到底是什么。性能

渲染管线,也称之为渲染流水线,能够理解为工厂的流水线工做,而在这里它的工做是让计算机把模型经过一系列的处理最终生成图像的过程,学习

网上也有人这么描述它:渲染管线是显示芯片内部处理图形信号相互独立的的并行处理单元。顶点管线在GPU中的做用就是处理几何数据,并将3D数据投射到二维的屏幕上。借用一个网友说的简单例子来通俗的说明一下顶点管线和像素渲染管线的做用。一个画家在作画的时候,都须要先把所画人或物的轮廓,框架画出来,这里咱们称之为“构图”;而后再根据光照进行着色,这里咱们称之为“渲染”。顶点管线和像素渲染管线所起的就是这两个做用,顶点管线和引擎负责把“轮廓、框架”画出来,而像素渲染管线和引擎则负责对画好的“轮廓、框架”根据光照等因素进行着色,构成一幅完整的图形。渲染管线直接关系到显卡对画面的渲染性能。测试

那为什么称之为固定呢?这是说芯片上一组电路已经固定实现了特定的运算功能,程序能作的只是提供场景数据以及微调运算功能的参数。咱们只能经过调用不一样的API组合实现特定效果,可是比较死板。.net

 

那么问题又来了,流水线的处理过程分哪些步骤呢?

关于OpenGL的流水线,你们能够看这里的图形流水线教程,很是详细。CSDN博客地址:http://blog.csdn.net/racehorse/article/details/6593719

在这里,我借助前人的经验,把相关的知识再进一步分享给你们。

 

一个固定渲染管线包括以下功能:

一、顶点变换(Vertex Transformation)

这里的顶点是信息的集合,包含空间中的位置、颜色、法线、纹理坐标等等。主要用于顶点位置变换、对每一个顶点计算光照、纹理坐标的生成以及变换

二、图元组合和光栅化(Primitive Assembly and Rasterization)

该阶段处理的是上一个阶段输出的变换后的顶点以及它们的链接信息。链接信息用来描述顶点如何组成图元(三角形、四边形等等)。利用在顶点变换阶段计算出的数据,结合链接信息计算出片断的数据。(例如,每一个顶点包含一个变换后的位置,当它们组成图元时,就能够用来计算图元的片段位置。另外一个例子是使用颜色,若是多边形的每一个顶点都有本身的颜色值,那么多边形内部片段的颜色值就是各个顶点颜色插值获得的。)另外此阶段还负责视锥体(view frustum)的剪裁和背面剔除。

光栅化决定了片段(fragment),以及图元的像素位置。这里的片段是指一块数据用来更新帧缓存(frame buffer)中特定位置的一个像素。一个片段除了包含颜色,还有法线和纹理坐标等属性,这些信息用来计算新的像素颜色值。本阶段的输出包括帧缓存中片断的位置,以及通过插值后的片断信息。

三、片段纹理化和色彩化(Fragment Texturing and Coloring)

此阶段的输入是通过插值的片断信息。在前一阶段已经经过插值计算了纹理坐标和一个颜色值,这个颜色在本阶段能够用来和纹理元素进行组合。此外,这一阶段还能够进行雾化处理。一般最后的输出是片段的颜色值以及深度信息。

四、光栅操做(Raster Operations)

此阶段的输入包括像素位置、片段深度和颜色值。这个阶段对片断进行一系列的测试,包括:剪切测试(scissor test)、Alpha测试、模版测试、深度测试

若是测试成功,则根据当前的混合模式(blend mode)用片断信息来更新像素值。注意混合只能在此阶段进行,由于片段纹理化和颜色化阶段不能访问帧缓存。帧缓存只能在此阶段访问。

 

一幅图总结固定功能流水线(Visual Summary of the Fixed Functionality)

下图直观地总结了上述流水线的各个阶段:

该图的出处http://blog.csdn.net/racehorse/article/details/6593719

 

而在咱们即将进行的着色器编程中,上述的流程,有两个阶段被编程替代

一、顶点变换(Vertex Transformation) 这个阶段使用顶点着色器实现。

二、片段纹理化和色彩化(Fragment Texturing and Coloring) 这个阶段使用片断着色器实现。

 


 

 

在OpenGL 3.0版本以前(包含3.0),或者使用了兼容模式(compatibility profile)的OpenGL环境下,咱们还可使用以前的固定渲染管线,在不使用着色器的状况下处理几何与像素数据。

但从3.1版本开始,固定渲染管线从核心模式(core profile)去除,因此若是使用该版本以后的核心模式来编程的话,咱们必须使用着色器。

  

GLSL在OpenGL 2.0版本左右发布的(在以前是属于扩展功能)。与OpenGL与时俱进,它是一种专门为图形开发设计的编程语言,但咱们能够从其身上找到C/C++的影子。

每个着色器代码看起来像是一个完整的C程序,一样有一个main入口函数。可是与C不一样的是,着色器的main函数没有任何参数,在某个着色阶段中的输入和输出的全部数据都是经过着色器中的特殊全局变量来传递的。最重要一点是,不要把它们与应用程序中的全局变量混淆,它们二者没有任何关系。

 

#version 430 core
 
in vec4 vPosition
in vec4 vColor;

out vec4 color;

uniform mat4 ModelViewProjectionMatrix;
 
void main(){
    color = vColor;
    gl_Position =  ModelViewProjectionMatrix * vPosition;
}

正如上面的代码,OpenGL会使用输入和输出变量来传递着色器所须要的数据,变量的值会在OpenGL每次执行着色器的时候更新。

还有一种是变量是直接从OpenGL应用程序中接收数据的,称为uniform变量。uniform表示惟一,对全部几何图元的值都是一致的,除非应用程序对它执行了更新,不然着色器是并不会影响它的值的变化的。

 


 

在这一小节中,咱们主要了解什么是着色器,为何会出现着色器,它和固定管线有什么区别。另外,还有图形流水线知识,下一小节,咱们会继续学习GLSL的基本变量以及相关操做。

 

 

2015.08.12

     广州

相关文章
相关标签/搜索