写点什么

顶点和片段着色器

  • 2011-11-03
  • 本文字数:3513 字

    阅读完需:约 12 分钟

目录

需求

预备知识

最好对 Stage3D API 有基本的了解。最好拥有使用 VertexBuffer 的经验。在完成本教程之前,一定要阅读这个关于 Stage3D 的系列的上一篇教程( Stage3D 的工作原理)。

用户水平

中级

需要的产品

本教程将介绍着色器。着色器是 Stage3D 呈现管道的核心。您将学习什么是顶点着色器和片段着色器,它们如何适合 3D 呈现管道,以及为什么需要它们。

使用着色器

在本系列的上一篇介绍Stage3D 工作原理的文章中,您已知道Stage3D 基于一种可编程图形管道。

Stage3D 的可编程图形管道非常有用,因为您可以对呈现行为进行编程。这是对旧有的固定函数图形管道的一项重大改进,涉及到向 GPU 提供数据,以便它可以在无需任何控件的情况下呈现。

但是,它还意味着为了使用 Stage3D,您需要负责编写这些实际使管道可编程的可编程代码。

图形管道中的可编程代码是一些称为着色器的程序。着色器有两种工作方式:顶点着色器和片段着色器(也称为像素着色器)。要完全使用 Stage3D 呈现所有内容,您需要编写至少 1 个顶点着色器和 1 个片段着色器,否则您的图形管道将无法编程,也不会生效。

着色器是一些在您的图形硬件 GPU 上运行的小程序,不会像正常的 ActionScript 代码一样由 CPU 执行。这是着色器程序与常规代码之间最重要的区别。

着色器就是 GPU 程序。

在 Stage3D 内,着色器使用一个名为 Program3D 的特殊的 Stage3D API 类包装。Program3D 提供了创建着色器实例并将它上传到 GPU 所需的功能。着色器程序然后即可执行,Stage3D API 允许在您的主要 ActionScript 代码与着色器程序之间通信。

着色器运行速度很快。但请注意,ActionScript 是一种较慢的语言。但是当运行 ActionScript 时,因为您是在一个虚拟机内执行代码,所以该语言的运行速度比 C++ 等原生语言更慢。这就是如今的许多 AAA 游戏仍然使用 C++ 编写的原因。

在首次使用 Flash 时,您可以创建 GPU 原生的着色器程序——以便它们可以完整的(GPU)原生速度运行。

理解着色器如何适合可编程图形管道

可编程图形管道描述了 Stage3D 内容呈现的方式(参见图 1)。

图 1. 可编程图形管道结构图。

查看上图,留意顶点着色器和片段着色器是如何构成管道中的重要部分的。

当呈现一个几何形状时,您将有一个称为 VertexBuffer 的顶点流,它生成几何三角形。这个来自顶点缓冲区的顶点流提供作为顶点着色器的输入,它可以以可编程的方式处理顶点数据。顶点着色器输出供 GPU 用于组装三角形。这些三角形然后在视口中经过恰当地切分和剔除,随后发送到 Rasterizer 块中,该块生成一个新的输出流,其中包含所谓的片段:微型的数据结构,每个片段与屏幕上出现的一个三角形像素相对应。

片段的数据内容主要有顶点着色器确定。事实上,顶点着色器有能力将顶点属性参数作为它的输出传递。Rasterizer 所做的是将顶点着色器输出的针对每个顶点的数据插入到三角形中,使屏幕上的每个片段(三角形像素)获得这个特定像素的正确值。

例如,想象您的顶点缓冲区指定了一种顶点颜色作为顶点属性,您的三角形有两个顶点指定为白色,一个顶点指定为黑色。顶点着色器将把这些顶点颜色传递到它的输出,传递到管道中的以下块中。然后,一个与三角形中某个位置相对应的片段将收到一个具有一定灰度的颜色:白色顶点和黑色顶点颜色的插值。这种灰度对于接近白色顶点的片段会更亮,对于接近黑色顶点的片段会更黑。

这些插入的未处理的片段然后作为输入发送到片段着色器,后者使用该数据建立最终的像素颜色。

除了它作为输入收到的这些片段,您也可以使用 ActionScript 代码向片段着色器发送一个或多个输入纹理,片段着色器可对这些纹理进行采样。

使用顶点着色器

顶点着色器是在 GPU 上运行的小程序。从名称可以看出,可通过处理它们来处理顶点。顶点着色器是处理顶点的微型程序。

一般而言,您将使用您的几何信息创建一个 VertexBuffer 并将它传递给 GPU。然后您将使用一种着色语言(比如 AGAL)编写一个顶点着色器。会为您的 VertexBuffer 中的每个顶点调用顶点着色器程序。

这就像有一个围绕顶点程序,执行以下任务的 for 循环:

复制代码
for (var i:int = 0; i < vertexBuffer.length; i++)
{
executeVertexShader(vertexBuffer[i]);
}

即使您没有看到 for 循环。所以会处理 VertexBuffer 中的所有顶点。

您也可以将常量值以常量寄存器的形式从 ActionScript 传递到 VertexShader。每次您希望运行着色器(每次您调用 Context3D::drawTriangles 方法来呈现一个结构),您都可以传入一个不同的值。着色器可以处理这个常量值,以调整它的算法和输出。

顶点着色器的输入是一个 VertexBuffer,它由一个或多个顶点属性流组成。在最低限度,一个顶点缓冲区必须包含顶点位置。这些顶点位置通常指一个位于每个 3D 模型本地的坐标系统(每个模型拥有自己的原点)。顶点着色器将位置传输到屏幕空间,以便它们可以正确地显示。顶点缓冲区可能还包含其他顶点属性,比如顶点颜色或纹理 UV 坐标。顶点着色器通常传递这些值作为输出(最终在处理它们之后),以便它们可以由 Rasterizer 插入并作为输入传入到片段着色器中。

顶点着色器最明显和自然的用途是对屏幕中的几何形状执行矩阵变换。您会获得本地空间中的所有顶点。并将变换矩阵传递给顶点着色器。顶点着色器将使用矩阵转换 VertexBuffer 中的所有顶点。它会非常块地执行此任务。比您在 ActionScript 中编写代码要快得多,因为它是硬件加速的。

有趣的是,顶点着色器完全是可编程的。您可通过您喜欢的任何方式修改您的几何形状。例如,一个修改顶点位置的典型应用是骨头的创建:您可以定义一组骨头、您的几何形状的一个框架,以及一个皮肤(网格)。当骨头旋转时,它们位于一个层次结构中,它们修改其皮肤的形状。这正是创建手指动画的方式。这么做的最佳方式是将骨头的旋转(转换)传递给一个顶点着色器,让顶点着色器修改皮肤,以便它看起来得到了恰当的绘制和变形。

顶点着色器还有许多其他的应用:模拟软布的外观,或者变形物体。创建两个网格,它们具有相同数量的顶点,让顶点着色器依据变形参数将网格 1 变形为网格 2。

使用片段着色器

像顶点着色器一样,片段着色器也是在 GPU 上运行的小程序。从名称可以看出,片段着色器处理片段——它们负责输出每个呈现的三角形像素的最终像素颜色。

基本而言,它的工作原理如下:片段着色器以输入的形式收到顶点着色器通过管道传递的所有这些片段。如上所述,到达片段着色器的片段是顶点着色器的顶点属性输出的插入版本。

片段着色器执行流程在本质上就像一个隐藏的循环。如果您想象将您未处理的片段添加到某种称为的 fragmentStream 的流中,那么片段着色器的执行将等效于以下代码:

复制代码
for (var i:int = 0; i < fragmentStream.length; i++)
{
executeFragmentShader(fragmentStream[i]);
}

可以说,输入 fragmentStream 是未处理的。这意味着片段着色器可以处理它,计算该三角形屏幕像素的最终颜色。

片段着色器真正位于可编程图形管道的核心。片段着色器的最常见用途是计算从顶点属性颜色(用于顶点着色几何体)或从纹理和相关的顶点属性 UV 纹理坐标(用于纹理几何体)开始的各种三角形像素颜色。

但片段着色器并不仅限于创建这些简单效果,实际上,片段着色器可用于创建您在现代 3D 游戏中看到的所有令人惊艳的 3D 效果。例如,动态光线效果大部分都是使用片段着色器完成的。可以想象,动态光线意味着依据场景中存在的光线、它们相对于我们的几何体的位置,以及几何体的材质来计算像素颜色。这正是动态光线最常使用片段着色器创建的原因。

反射效果,比如水或环境映射,都是使用片段着色器创建的。可使用片段着色器创建的效果非常丰富,这些基本效果仅仅是所有可能性的冰山一角。

最后,您在屏幕上看到效果取决于片段着色器。所以片段着色器是管理实际呈现的内容的代码。

延伸阅读

在本教程中,您学习了使用顶点着色器和片段着色器的概念。这些着色器构成了 Stage3D API 中的呈现管道的核心。着色器可用于创建所有类型的 3D 图形效果,有大量在线文献介绍了基于着色器的技术。请继续阅读这个 Stage3D 系列中的下一篇教程,了解着色语言,专门学习一下 AGAL (Adobe Graphics Assembly Language)。

要更详细地研究着色器,我建议阅读 nVidia 所编写的流行的“GPU Gems”图书,它们已免费在线发布。它们没有专门介绍使用 Flash 和 Stage3D,但提供了对您可以使用着色器创建的效果的有用概述:

查看原文: Vertex and Fragment Shaders

2011-11-03 00:005660

评论

发布
暂无评论
发现更多内容

AI系统伦理道德风险之透明度验证

陈磊@Criss

15年了,我们到底怎样才能用好 Serverless

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 4 月 PK 榜

千行百业的共同选择,华为云为何成为央国企首选云?

科技热闻

面试何惧调优!腾讯技术官私藏的性能优化方案手册,原理实战齐全

Java 性能优化 性能调优

window c++ select 参数列表介绍

linux大本营

TCP socket select I/O 多路复用

CutMix&Mixup详解与代码实战

华为云开发者联盟

人工智能 华为云 数据增强 华为云开发者联盟 企业号 4 月 PK 榜

Photoshop崩溃怎么办无法打开 Photoshop

互联网搬砖工作者

Neural Filters神经滤镜插件如何安装?PS神经滤镜插件安装教程

互联网搬砖工作者

堪称一绝!阿里技术人都用的Nginx手册,应用到架构齐全

Java nginx

为什么我们的微服务中需要网关?

Java 微服务 网关

linux 自定义段 c

linux大本营

Linux C语言 系统调用

软件测试/测试开发丨常见面试题与流程篇(附答案)

测试人

软件测试 面试题 自动化测试 测试开发

私有云裸机物理服务器角色规划

穿过生命散发芬芳

私有云 三周年连更

SBOM喊话医疗器械网络安全:别慌,我罩你! Part Ⅰ

安势信息

网络安全 SBOM 医疗器械 SBOM应用

算法题每日一练:连续子数组的最大和

知心宝贝

数据结构 算法 前端 后端 三周年连更

华为云联合多家单位正式开源云原生多沙箱容器运行时Kuasar

华为云开发者联盟

云原生 后端 华为云 华为云开发者联盟 企业号 4 月 PK 榜

详解Redisson分布式限流的实现原理

Java 分布式限流 redisson

华为云尚海峰:三个“全面”,助力央国企深度用云

科技热闻

从领先实践看港口行业资产管理数智化变革

用友BIP

最佳实践|如何写出简单高效的 Flink SQL?

Apache Flink

大数据 flink 实时计算

Flink 2.0 启航,开启全新篇章

Apache Flink

大数据 flink 实时计算

【获奖案例巡展】信创先锋之星——江西金发基于分布式数据库的互联网金融业务系统

星环科技

分布式数据库

c4d R2023 让您的三维动画设计更简单~~

真大的脸盆

Mac Mac 软件 三维动画设计 动画设计工具

关于C语言的系统相关的桌面程序编程书籍推荐吗

linux大本营

C语言

linux unlikely函数

linux大本营

Linux unlikely函数

顶点和片段着色器_语言 & 开发_Marco Scabia_InfoQ精选文章