原文:Stage3D / AGAL from scratch. Part V – Indexes and culling mode
eg.如果你E文不错的话 还是看E文比较带劲。本人E文非常烂,若有偏差请指出。
索引用于什么地方?
在前面的文章中,介绍了索引 和索引缓冲,我把索引缓冲比喻成连线游戏中的数字,在屏幕上渲染图形的时候,显卡需要知道如何画三角形
例如有8个顶点,想象成构建一个8个顶点的立方体,如果仅仅是给出8个顶点数据,而没有进一步的指令编码,那显卡根本不知道你想画啥
可能你想渲染出一个封闭的四方盒子,但也许你是想画一个开盖的四方盒子,有也许你想打开四方盒子中的两面。。。
索引就是你想 根据顶点画图形的步骤 或者说是顺序,绘画方案 总之一个意思。索引告诉显卡怎么在顶点上画画 顶点告诉显卡在那里画画。就是这样~
在渲染三角形的过程中 可能会用到同一个顶点多次,无论在显卡中渲染什么图形,索引缓冲的长度(并非顶点)的都必须是3的倍数,因为我们能渲染的最简单的物品是三角形嘛。。然后其他全部都由一个一个三角形组成。
对于索引(也翻译为片段)我们仅仅需要把它理解为 顶点之间连接的指针。所以索引值其实就是顶点的渲染顺序定义(那个点开始 那个点结束 那个点连那个点),下面是绘制立方体的两个面的索引抽象图:
我们把索引和顶点联系起来,例如顶点A 对应 索引 0 , B对应1
上图有8个索引:
A B C D E F G H
则按照上图渲染顺序 索引缓冲的数据应该如下:
0, 1, 2, 1, 2, 3, 0 ,4 ,5, 0, 5, 1(按照图的意思 应该是 0 1 2,2 1 3 , 0 4 5,0 5 1 吧?)
那么 我们如果把顶点缓冲的顶点顺序换下 把C D 互调的话,相同位置渲染图片上的图形 那索引缓冲的值也要变换为:
0, 1, 3, 1, 2, 3…
理解了么 索引缓冲就是那么简单~
索引和三角形淘汰:
在默认的前提下,GPU渲染每一个索引和顶点共同定义的三角形,无论这个三角形是否落在剪切空间上(Clip Space 上一篇说的东西 指你所能看到的显示界面大小的区域)
比较高效的优化方法 是 只渲染 落在ClipSpace区域的三角形 (反正其他三角形也看不到 渲染出来浪费GPU空间 )。先忽略其他细节,现在只考虑渲染可见三角形 看看在性能的对比上如何。下面将渲染一个不透明的球体为例子:
这种方式叫做三角形淘汰模式,对于英语不是母语的我 来理解culling。。淘汰意味着删除(译者的母语也不是英语啊 ),在渲染三角形的时候 可能在渲染管道中 跳过并非facing (不在显示界面上 )的部分,而只渲染 能落在界面上的部分(作者的理解 好像是那么回事~)。
淘汰模式可以使用下列四种模式 ,四个三角形相对于视图点的方向的常量:
- Context3DTriangleFace.NONE : 默认模式 渲染三角形的全部部分,没有那一个方向会被淘汰(忽略?减去?差不多的意思)
- Context3DTriangleFace.BACK : Triangles are rendered only if they are “facing” the view. ie, triangle’s back face is culled.
- Context3DTriangleFace.FRONT : Triangles are rendered only if they are not “facing” the view, triangle’s front face is culled.
- Context3DTriangleFace.FRONT_AND_BACK : Nothing is rendered, since both faces are being excluded.
- (上面的各自模式 在代码中试一次就知道啥意思了)
但是那一个是正面的?
你可以猜测我们怎么判断三角形的那一面是正面(front face)?其实这是非常简单的,规则就是:如果是顺时针的渲染方向 那就是正面,如果是逆时针的渲染方向 那就是 反面。
第一个的顺序是 0 1 2
第二个的顺序是 0 2 1
下面找到hello三角形那边源码,在render函数中加入:
[code lang=”as”]
context.setCulling(Context3DTriangleFace.BACK);
[/code]
设置为反面模式,其实反面模式是在Away3D中使用的,现在你尝试上传索引缓冲的时候 发现屏幕没有渲染出三角形
淘汰模式和 双面多边形(这啥啊?)
在大部分的引擎中 渲染模式都设置为BACK,这以为这你在自己的三角形中只能使用FRONT模式,如果不使用淘汰模式,那会有一个双面选项,
双面选项能是得多变形可以显示为双面(?)
绘制出一个双面三角形 是非常简单的,仅仅需要增加一倍的索引指令,把索引指令分为相等的两部分,一部分是设置正面模式 一部分是设置反面模式
修改之前的三角形代码,把索引缓冲区改为:0, 1, 2, 0, 2, 1..
下面是最简单的方式,直接用处理数组的函数:
[code lang=”as3″]
var indexes:Array = [0, 1, 2];
if(_doubleSided){
indexes = indexes.concat(indexes.reverse());
}[/code]
顶一个……………………………………………….
支持楼主精彩博文!