level 5
由于百度写代码实在是让人头疼,所以我尽量不用代码。
OIT全称Order Independent Transparency,在进行物体透明度混合的时候我们时常要关注透明部分的深度值,因为虽说是3D,其实画图还是画在2DTexture上的,所以透明部分要按照深度值排序渲染。
3D行业发展到现在OIT的实现方法肯定很多,我这里使用的是参考别人的和SDK里面的OIT Sample自己改进的一个方法(我会在最后给出参考资料的链接),由两个PASS完成,你要是跟我说有一个PASS就能完成的OIT那是不可能的,单纯的关闭深度测试来实现称不上是OIT。
下面介绍的方法可以实现多种输入流格式的物体色彩半透明混合,而且考虑了背景色,至于深度值重写下面我再详细介绍(虽然能够实现,但是我有更好的方法,只是还没写而已= =)
先创建两张缓存





一张FLBuffer是用来存放(深度,颜色(包含透明度)和下一个结点的地址)的结构缓存,没错,我将要使用链表,我们将为窗口中每个点创建一条链表,但仅靠它是不能完成链表的功能的,所以有第二张缓存startOffserBuffer,这是一张和窗口等大的缓存,它对应窗口上的每一个像素点,存放的是这个像素点位置上链表的起始位置,以数组的下标代替地址。然后用这2张缓存创建4张视图,分别为
FLBufferSRV,startOffsetBufferSRV
FLBufferUAV,startOffsetBufferUAV
SRV是支持读的视图
UAV是支持读和写的视图
它们的数据是和创建它所用的Buffer相关联的,因此我们可以在FLBuffer需要写的时候时候它的UAV,需要读的时候使用SRV,这样能加快CPU读取速度。
另外链表的结构如下


在Pass1里,我们正常写入顶点数据,但在经过PS的时候,把深度测试设置成测试但不写入,我们把数据储存到FLBuffer里面,然后使用clip(-1),因此不必解绑RenderTargetView也没关系,clip(-1)会丢弃这个像素点,不过我们已经事先把像素点存到了缓存里面,位置为从FLBuffer[0]开始存到渲染结束.....突然发现这里要讲好多东西= =蛋疼



