引擎中的 ShaderTree 概要设计

Shader
Ø       Shader描述了如何渲染物体的信息,包括Texture SetupMaterial PropertyRender StateBlend SetupPixel ShaderVertex ShaderRender Target Setup等等。Shader并不直接和Geometry相关联,因为对于同一个Geometry,有可能会用不同的Shader来渲染。
Ø       Shader Tree 是为了 Minimum Shader State Change,树中每一条 path 都是一个 shader
 
 Shader Tree
Data Structure
 
Ø         ShaderTreeST): node 的容器,它除了遍历树的功能之外还包含创建 ShaderPath 的功能。
Ø         ShaderTreeNodeSTN):用于构成 ST 的主要数据结构,ST中的非叶 STN 存储了一个RenderGroupST中的Leaf STN存储了Batched Geometry。多个Leaf节点可以共享一个Batched Geometry。当遍历ST时遇到Leaf  STN就开始绘制Batched Geometry
Ø         RenderStateRS):渲染状态的封装。
Ø         RenderStateGroupRSP):渲染状态组,将相同概念的渲染状态组合在一起,分组标准参考 D3D10 State Object 中的 RasterizerDepth StencilBlendSampler
Ø         CSCT状态改变开销表,预定义生成。
  
The Policy of Build the Shader Tree
 
在遍历 SG 中,如果一个 geometry 可视,则将累积的 Shader 和这个 Geometry 送到 ShaderTree 中构建 ST。在构建之前先对累积的 Shader 中的 state list 按照 Render State Grouping 规则组合成 RenderStateGroup list,按照 CSCT Cost 的大小对这个列表排序,然后将按照顺序构建 STP,每个 RenderStateGroup list cost 最小的 RenderStateGroup STN 作为 ST 的叶子节点。所以从 ST Root Leaf 是按照 cost 的大小排序的,这样就能做到最小状态切换。每个 Leaf 和使用这个 shader path geometry 关联,这样每个 leaf 就会有一个 geometry list,然后交给 RenderSystem 对这个 geometry list 排序,再batch。这样就完成了一个 ST 的构建工作。
 
Build shader tree pseudo code
 
BuildTreePath( ShaderStack& shaders, Geometry* pGeometry )
{
// 根据 Accumulate Shader 生成 RSG 列表
       RenderStateGroupList rsgs = GenerateRenderStateGroup( shaders );
       //按照 CSCT Cost 的大小对这个列表排序
SortRenderStateGroupByCSCT(rsgs );
// 获取 RSG 列表的最大项和 ST 的根节点
RenderStateGroup& rsgRoot = rsgs.first();
ShaderTreeNode* pSTRoot = GetRoot();
// 调用内部的构建 path 的函数
_BuildTreePath(pSTRoot, rsgRoot );
}
 
_BuildTreePath ( pSTNodestateGroup )
{
       Bool bInsert = true;
       // 遍历当前 STN 的每个子节点
       For each child in pSTNode
              // 判断是否与当前的 STN RSP相同
              If ( child.context == stateGroup)
                     // 相同则略过当前 STN,如果 RSG 列表还有下一项,则继续递归
                     bInsert = false;
                     if (state.hasNext )
                            _BuildTreePath ( child, stateGroup.next )
                     Else
                            // 当前 RSG 没有下一项,则将当前的 Geometry 加入到当前的 STN 中。
                            AddGeometry( child, pGeometry );
                    End if
                    
              End if
       End for
// 如果不相同,则插入标志为真
       If ( bInsert )
              // 用当前的 RSG 创建一个 STN并加入到当前的 STN 为子节点
              Create newSTNode with this stateGroup
              pSTNode.AddChild(newSTNode);
              // 如果 RSG 列表还有下一项,则用新创建的 STN 继续递归
              if (stateGroup.hasNext )
                     _BuildTreePath (newSTNode, stateGroup.next );
              Else
                     // 当前 RSG 没有下一项,则将当前的 Geometry 加入到当前的 STN 中。
                     AddGeometry(newSTNode, pGeometry );
              End if
       End if
}
 
TODO
Ø         Accumulate Shader 的算法。
Ø         CSCT的构建,以及构建标准。
Ø         加入Geometry渲染优先级。
Ø         半透明和实体物体的区分。
Ø         Multi-pass ShaderTree 中的表示。
Advertisements
此条目发表在DreamEngine 3D 图形引擎开发分类目录。将固定链接加入收藏夹。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s