“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

顶点和片段着色器

  • 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:005248

评论

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

BaikalDB在大规模数据场景的挑战和实践

百度开发者中心

最佳实践 方法论 存储系统

开源应用中心|这款漂亮的国产开源论坛系统,放着不用太可惜!

开源软件

一文读懂 OceanBase 数据库的启动恢复代码解析

OceanBase 数据库

数据库 分布式事务 oceanbase OceanBase 开源

谈 C++17 里的 Singleton 模式

hedzr

c++ 算法 设计模式 Singleton

【网络安全】漏洞复现有多少种方式?

网络安全学海

php 网络安全 信息安全 WEB安全 安全漏洞

未来10年,C++5个非常有前景的就业方向

hanaper

Android ABI

Changing Lin

9月日更

高可用 | Xenon 实现 MySQL 高可用架构 常用操作篇

RadonDB

MySQL 数据库 RadonDB

“吾道一以贯之”:华为Petal One的新格局

脑极体

fil矿机组装教程是什么?fil矿机算力单位有哪些?fil矿机冗余是什么?

fil矿机组装教程是什么 fil矿机算力单位有哪些 fil矿机冗余是什么

中移“校企行”专项行动即将开赛,你准备好了吗?

创业邦

Python代码阅读(第23篇):将变量名称转换为短横线连接式命名风格

Felix

Python 编程 Code Programing 阅读代码

09. 深度学习携手大数据引领第三AI热潮--何为深度学习?

数据与智能

人工智能

投资filecoin的最佳选择是?Filecoin挖矿的是如何月入上万的?

区块链 分布式存储 IPFS filecoin挖矿 投资filecoin

如何使用 Redis 实现后台房间的数据管理?

ZEGO即构

redis 架构 音视频

什么是低代码?低代码开发对企业有哪些特殊作用和优势?

优秀

低代码开发

人能靠自驱来学习吗?

石云升

学习 9月日更

打一把游戏看一场病:当VR成为“数字新药”

脑极体

LeetCode刷题704-简单-二分查找

ベ布小禅

9月日更

爱奇艺本地实时Cache方案

爱奇艺技术产品团队

分布式 高并发 cache

filecoin今日价格行情?fil币能涨到1万一枚吗?

区块链 分布式存储 fil币价格预测? filecoin挖矿 filecoin价格行情

PhxSQL设计与实现

OpenIM

OpenSSL国密爆出8.1分高危漏洞CVE-2021-3711

腾讯安全云鼎实验室

漏洞分析 openssl

pnpm原理

法医

大前端 npm 9月日更

【得物技术】直播服务监控告警归因实践

得物技术

稳定性 服务 直播 告警 问题排查

🚄【Redis干货领域】从底层彻底吃透RDB原理(基础篇)

洛神灬殇

redis RDB 快照 rdb分析 9月日更

网络攻防学习笔记 Day125

穿过生命散发芬芳

9月日更 互联网安全

Erda 系列 Meetup「成都站」携手SOFAStack 和你聊聊云原生基础设施建设那点事儿

尔达Erda

开发者 云原生 活动 技术人

学习笔记20210903(python测试类,贝叶斯定理)

姬翔

9月日更

直播回顾 | 做一个有格局的工程师

鉴释

创业 工程师 CEO

Java + opencv 实现性别识别

张音乐

Java OpenCV 9月日更 性别识别

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