【DirectX11】第二篇 DirectX11渲染管线之Input Assembler Stage(IA)

本系列主要翻译和参考《Real-Time 3D Rendering with DirectX and HLSL》一书(感谢原书作者),同时会加上一点个人理解或拓展。

这里是书中的代码和资源。


DirectX11 渲染管线

一般计算机中共有两个处理器是你可能会对其进行编程的,一个是central processing unit(CPU),一个是GPU。这两个组件有着截然不同的硬件结构和指令集。在图形编程领域,你编写的软件可能两方面都要涉及,对于CPU,你可能会使用到例如C++这样的编程语言,而对于GPU则需要使用诸如HLSL这样的语言。大部分关于图形编程的文章要么集中于CPU方面要么是GPU方面,这些内容其实都是有紧密联系的。在本书中,你将可以同时了解到两方面的内容。

DirectX当中的DirectX 3D API是本书着重关注的部分。Direct3D是用来绘制3D图形的系统接口,他还定义了怎样将实时图形渲染到屏幕的一系列步骤。这些步骤就被称之为DirectX3D图形渲染管线(详见图1.1)。在这张图中,单向箭头标识了数据是怎样从一个阶段传输到下一个,双向箭头则标识了资源和哪些渲染阶段间可以进行数据读写。那些可以用HLSL编程的模块已经用圆角矩形标识出来。接下来的内容将会详细介绍渲染管线中的各个模块。

输入装配阶段:The Input-Assembler Stage(IA)

输入装配阶段是渲染管线的入口,也是第一个阶段,在这个阶段里你需要提供待渲染对象的顶点和索引数据。输入装配阶段将这些数据“装配”成基本类型数据(例如:点列表,线条带,三角列表)并根据需要将数据输出给顶点着色渲染阶段。

Vertex Buffers顶点缓存

一个顶点至少包含了在3D空间中的一个位置。之所以说至少是因为顶点还可以包含颜色信息,法线信息(用于计算光照),纹理坐标信息等等。所有这些数据都可以在输入装配阶段进行顶点缓存。Direct3D中定义的这些顶点信息完全可以由程序员进行操作。你可以定义顶点所要包含的信息并通过input-layout对象定义顶点缓存数据如何流入IA阶段。之后的文章(原书Part III,Rendering with DirectX)中将会介绍如何定义顶点缓存以及input layout对象,现在只是大概的介绍一下这些术语。

两个顶点代表线段的两个端点,三个顶点可以代表一个三角形(如图1.2)。

Index Buffers索引缓存

索引缓存是第二种在输入装配阶段推荐的输入类型。索引缓存的定义关联了顶点缓存中的某些顶点,可以用来减少需要多次使用到的顶点的重复。想象以下场景:你需要渲染一个矩形(或宽泛的说,四边形)。这个四边形至少需要定义四个顶点。但是Direct3D并不支持将四边形作为基础类型(因为根本没有必要专门定义一个四边形,所有的四边形都可以拆分成三角形)。为了渲染这个四边形,你需要将其拆分成两个由三个顶点构成的三角形(如图1.3)。所以,现在你需要总共六个顶点信息,而不是四个,其中必然有两个顶点信息是重复的。但如果定义了索引缓存,你就可以通过定义四个顶点信息和六个与顶点缓存相关的索引信息来完成渲染。

现在,你可能会思考一个问题,“我怎么通过增加索引缓存来减少我所使用的整体数据大小呢?”那么我们需要再考虑两种情况,通过结合上面提到的四边形进行具体数据分析:

  • 第一种情况

    你的顶点数据只包含3D位置信息(x,y,z),每个轴向需要一个32-bit来保存这个浮点数(每个轴向为4byte),那么每个顶点需要12byte。所以在不包含索引缓存的情况下这个四边形只需要72字节保存(6 vertices * 12 bytes/vertex)。如果加上索引缓存,你的顶点缓存需要的空间是48byte(4 vertices * 12 bytes/vertex)。以16bit的int类型数据来保存索引,则你需要额外12bytes(6 indices * 2 bytes/index = 12 byte)。这时,总共需要60byte来存储这个四边形。这么看的话好像也没节省很多空间。

  • 第二种情况

    当你的模型中不仅包含位置信息,还可能包含16byte的颜色信息,12byte的法线信息以及8byte的纹理坐标信息。那么每个顶点将需要多花费36byte的空间。或许当模型不是太大的时候并不会有很多影响,但如果模型具有成千上万的点时你会发现多出来的空间占用是相当可观的。还有,你不仅需要考虑空间占用的大小,还有当CPU和GPU之间进行数据传输时,是需要通过图形总线(例如PCI Express)来传输的,这种总线的传输速度通常非常慢(相比于CPU向RAM传输,以及GPU向VRAM传输),所以如何减少数据对你来说将会是至关重要的。

Primitive Types基本类型

当你向IA阶段提供顶点缓存数据时,你也必须定义这些顶点的拓扑结构,这决定了渲染管线将如何解释这些顶点。DirectX3D提供了以下几种基本类型(如图1.4和1.5):

- Point list 点列表:一系列单独渲染毫无关联的点

- Line list 线列表:一系列成对关联的点,这些一对一对的点之间是没有关联的

- Line strip 线条带:一系列成对关联的点,但每对点的末点会和下一对点的起点有关联

- Triangle list 三角列表:是我们最常见的拓扑结构,在三角列表中每三个顶点组成一个独立的三角形。三角形之间公用的点将会重复出现(除非定义了索引缓存)。

- Triangle strip 三角条带:每三个顶点构成一个三角形,公用的顶点将不会重复,所以顶点间会密切的连在一起。

Primitive with Adjacency邻接基元

从DirectX10开始,Direct3D已经加入了包含邻接数据的基本数据。对于邻接基元来说,你不只要定义基本数据,还需要定义围绕在这个基元周围的数据。(如图1.6)这是用来做几何着色器的,这里每个特定的集合着色程序需要访问邻接三角形。临界三角形需要和原始三角形一起被提交给顶点/索引缓冲区,并且用D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ这个拓扑结构。注意到邻接三角形只是被用来作为几何着色器的输入,并不会被画出来。如果没有几何着色器,邻接三角形也还是不会被画出来。

Control Point Patch Lists控制点片

控制点片作为一个拓扑结构提供给细分曲面阶段使用。相关内容将会在后面的几何细分曲面着色器文章中介绍。

参考文章:
关于输入装配阶段的详细内容和具体实现请参考[这篇文章](http://www.aiseminar.com/bbs/home.php?mod=space&uid=3&do=blog&id=2622)。
在做完IA部分的资料翻译和整理后发现篇幅比预期长一些,于是剩下的几个渲染阶段将会在下一篇文章中总结。
时间: 2024-10-11 02:05:41

【DirectX11】第二篇 DirectX11渲染管线之Input Assembler Stage(IA)的相关文章

Python之路【第二篇】:Python基础(一)

Python之路[第二篇]:Python基础(一) 入门知识拾遗 一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. 1 2 3 if 1==1:     name = 'wupeiqi' print  name 下面的结论对吗? 外层变量,可以被内层变量使用 内层变量,无法被外层变量使用 二.三元运算 1 result = 值1 if 条件 else 值2 如果条件为真:result = 值1如果条件为假:result = 值2 三.进制 二进制,01 八进

「C语言回顾之旅」第二篇:指针详解进阶

说明: 第一篇回顾了指针的基本概念以及基本使用,因此对指针也有了一个较为清晰的思路,但实际上第一篇关于指针的内容是不太容易忘记的.这是第二篇中的内容是比较容易混淆,但对于指针的进一步学习也是非常重要的. 一.指向函数的指针 1.函数指针 ·函数指针即指向函数的指针,函数指针值为函数的入口地址,通过使用该指针,即可以使用该函数: ·编写一个程序返回两个数的最大值,通过函数指针调用函数: a.main函数代码如下: #include<stdio.h> int max(int *, int *);

转载:eclipse 搭建SSH项目(第二篇,有具体的项目例子)

原文地址:http://blog.csdn.net/yeohcooller/article/details/9316923 读博文前应该注意: 本文提纲:本文通过一个用户注册的实例讲解SSH的整合.创建Struts项目,整合Hibernate,整合Spring.最后总结如何熟练创建SSH项目. 仅是创建SSH项目,对于其他的扩展例如Struts的国际化,Hibernate的缓存优化,Spring的AOP等,本博文涉及不到.想学习更多的东西请搜索其他博文. 本项目的环境:Windows 8-64位

【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)

目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策略(MVC5+EF6) [第四篇]ASP.NET MVC快速入门之完整示例(MVC5+EF6) [番外篇]ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6) 请关注三石的博客:http://cnblogs.com/sanshi 数据库连接字符串 上一篇文章中,我们使用MVC的

【《Real-Time Rendering 3rd》 提炼总结】(二) 第二章 图形渲染管线 The Graphics Rendering Pipeline

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/70544201 这篇文章是解析计算机图形学界"九阴真经总纲"一般存在的<Real-Time Rendering 3rd>系列文章的第二篇.将带来RTR3第二章内容"Chapter 2 The Graphics Rendering Pipeline 图形渲染管线"的总结.概括与提炼. 文章分为全文内

SylixOS ARM BSP 第二篇【startup.S】

此篇博客为 SylixOS ARM BSP 编写连载的第二篇,主要介绍 startup.S 文件具体实现. startup.S 为 BSP 启动代码入口,通常由 bootloader 装载完 SylixOS 镜像后调用,下面以 S3C2440A 处理器为例,逐块介绍 startup.S 代码. #ifndef ASSEMBLY #define ASSEMBLY 1 #endif 此段代码告知后面引用的头文件,此文件为汇编程序. #include <arch/assembler.h> 引用操作系

kubernetes之CI/CD工具jenkins第二篇,helm的使用

1. kubernetes之CI/CD第二篇-jenkins结合helm部署应用: 1. 概述: ?? 在前期的博文中我已经初步介绍过kubernetes环境下的CI/CD的使用.主要是jenkins slave pod自动创建和销毁,当有jenkins job任务执行的时候,就会自动创建一个jenkins slave pod.在本篇博文中,我们将介绍jenkins生成slave pod的另外一种方法,就是在pipeline脚本里面定义slave pod的镜像等,同时将Dockerfile.Je

Android Metro风格的Launcher开发系列第二篇

前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客Android Metro风格的Launcher开发系列第一篇写了如何配置Android开发环境,只是用文字和图片展示了开发Metro风格Launcher的初步设计和产品要求,这一篇文章将会从代码上讲解如何实现对应的UI效果,好了,评书开讲! Launcher主体框架实现: Launcher主体框架我选用的是大家所熟悉的ViewPager控件,因为ViewPager

[C++11新特性]第二篇

0.可变数量参数,可变函数模版,变长模版类 c++98可变数量参数 #include<cstdio> #include<cstdarg> double SumOfFloat(int count, ...) { va_list ap; double sum=0; va_start(ap,count); for(int i=0;i<count;i++) sum+=va_arg(ap,double); va_end(ap); return sum; } int main() { p