Introductionto3DGameProgrammingwithDirectX12学。。。

Introductionto3DGameProgrammingwithDirectX12学。。。
代码⼯程地址:
曲⾯细分阶段包含渲染管线中的三个阶段,⽤以细分⼏何物体,它在顶点着⾊器和⼏何着⾊器之间。使⽤曲⾯细分的主要原因:
1. 基于GPU的LOD;
2. 物理和动画的优化,可以在低⾯模型上计算物理效果和动画,然后细分为⾼⾯模型⽤以渲染;
3. 节省内存(硬盘,RAM,VRAM)。
学习⽬标
1. 学习曲⾯细分使⽤的patch基元类型;
2. 学习曲⾯细分每个阶段的作⽤,以及他们的输⼊输出
3. 学习通过编写hull和domain着⾊器来细分⼏何体;
4. 学习曲⾯细分的不同策略,以及曲⾯细分的优化;
5. 学习贝塞尔曲线和平⾯的数学公式,以及如何⽤曲⾯细分来实现它。
1 曲⾯细分基元类型
当我们使⽤曲⾯细分渲染,我们不想IA阶段提交三⾓形列表,我们提交具有许多控制点的patches。D3D⽀持patches拥有1~32个控制点,并且由下⾯的基元类型定义:
D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33,
D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34,
D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35,
D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36,
.
.
.
D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63,
警惕沙尘暴的池塘效应D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
⼀个三⾓形可以被理解为⼀个具有3个控制点的三⾓patch((D3D_PRIMITIVE_3_CONTROL_POINT_PATCH),所以你依然可以提交你的三⾓形⽹格。四边形可以被提交为(D3D_PRIMITIVE_4_CONTROL_POINT_PATCH)。这些patch最终会被曲⾯细分阶段细分为三⾓形。
当传递控制点基元类型到ID3D12GraphicsCommandList::IASetPrimitiveTopology时,设置
D3D12_GRAPHICS_PIPELINE_STATE_DESC::PrimitiveTopologyType为D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH:
opaquePsoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
1.1 曲⾯细分和顶点着⾊器
因为我们提交的是patch的控制点,所以顶点着⾊器可以正常处理这些控制点(和顶点⼀样)。
2 HULL着⾊器
HULL着⾊器实际上包含2个着⾊器:常量Hull着⾊器(Constant Hull Shader)和控制点Hull着⾊器(Control Point Hull Shader)。
2.1 常量Hull着⾊器
常量Hull着⾊器针对每个patch执⾏,并且负责输出⽹格的曲⾯细分因⼦(tessellation factors);曲⾯细分因⼦命令曲⾯细分阶段对patch细分多少。下⾯是⼀个将拥有4个控制点的⽅块patch均匀细分3次的例⼦:
struct PatchTess
{
float EdgeTess[4] : SV_TessFactor;
float InsideTess[2] : SV_InsideTessFactor;
// Additional info you want associated per patch.
};
PatchTess ConstantHS(InputPatch<VertexOut, 4> patch,皮尔斯电子
uint patchID : SV_PrimitiveID)
{
PatchTess pt;
// Uniformly tessellate the patch 3 times.
pt.EdgeTess[0] = 3; // Left edge
pt.EdgeTess[1] = 3; // Top edge
pt.EdgeTess[2] = 3; // Right edge
pt.EdgeTess[3] = 3; // Bottom edge
pt.InsideTess[0] = 3; // u-axis (columns)
pt.InsideTess[1] = 3; // v-axis (rows)
return pt;
}
常量Hull着⾊器必须输出细分因⼦,细分因⼦取决于patch的拓扑结构。
除了细分因⼦(SV_TessFactor和SV_InsideTessFactor),你还可以输出其他patch的信息,让domain着⾊器接收并使⽤。
细分⼀个⽅块patch包含两部分:北极涛动
1. 四条边的细分因⼦⾓⾊四条边怎么细分;
2. 2个内部细分因⼦决定内部如何细分。
细分⼀个三⾓形patch同样包含两部分:
1. 3条边的细分因⼦;
2. 1个内部细分因⼦;
D3D11硬件⽀持的最⼤细分因⼦是64。如果所有细分因⼦都是0,那么当前patch就拒绝进⼊后⾯的阶段。它可以帮助我们基于patch在背⾯消除和视锥体裁切上实现优化。
1. 如果这个patch不在视锥体内,可以让他拒绝进⼊后⾯的阶段;
2. 如果这个patch是背⾯,可以让它拒绝进⼊后⾯的阶段;
具体裁切多少主要基于需求,不要做不需要的裁切来浪费性能。下⾯是⼀些常⽤的度量单位来决定裁切多少:
1. 于相机的距离;
2. 屏幕的覆盖率;
3. 三⾓形的⽅向和定位;
4. 粗糙度。
[Story10]给出了下⾯的优化建议:
1. 如果细分因⼦是1(也就是不细分),⾛⼀遍细分阶段流程是浪费GPU开销;
2. 因为是基于GPU实现的,不要细分⼀个覆盖⼩于8个像素的这种太⼩的三⾓形;
3. 批量调⽤具有细分的绘制调⽤(频繁打开和关闭曲⾯细分⾮常浪费性能)。
2.1 控制点Hull着⾊器
控制点Hull着⾊器输⼊⼀系列控制点,输出⼀系列控制点。它每次控制点输出的时候调⽤⼀次。⼀个Hull着⾊器是改变平⾯的表现,⽐如⼀个将普通的三⾓形(拥有3个控制点)修改为⽴⽅贝塞尔三⾓形patch(拥有10个控制点)。这种策略称之为N-patches⽅案或者PN三⾓形⽅案([Vlachos01])。对于我们的第⼀个Demo,我们只是简单的pass-through着⾊器,只传递控制点,不修改(驱动可以检测和优化pass-through着⾊器([Bilodeau10b])):
struct HullOut
{
float3 PosL : POSITION;
};
[domain("quad")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(4)]
[patchconstantfunc("ConstantHS")]
[maxtessfactor(64.0f)]
HullOut HS(InputPatch<VertexOut, 4> p,
uint i : SV_OutputControlPointID,
uint patchId : SV_PrimitiveID)
{
HullOut hout;
hout.PosL = p[i].PosL;
return hout;
}
Hull着⾊器通过InputPatch输⼊参数传进所有控制点。系统值SV_OutputControlPointID给出控制点的索引。输⼊控制点的数量不需要匹配输出控制点的数量。
控制点Hull着⾊器介绍了⼀些属性:
1. domain:patch类型:tri,quad或者isoline;
2. partitioning:指定细分的模式:
a、integer:新顶点添加/删除值根据整形细分因⼦,⼩数部分会⽆视;
b、Fractional((fractional_even/fractional_odd)):新顶点添加/删除值根据整形细分因⼦,但是通过⼩数部分滑动。
3. outputtopology:细分后的三⾓形的缠绕顺序,triangle_cw(顺时针)、triangle_ccw(逆时针)、line(针对线段的细分);
4. outputcontrolpoints:Hull着⾊器执⾏的次数,每次输出⼀个控制点。SV_OutputControlPointID给出输出点在Hull着⾊器中的索
引。
5. patchconstantfunc:常量Hull着⾊器函数的名称;
6. maxtessfactor:提⽰驱动指定你的着⾊器使⽤的最⼤细分因⼦。这个可以让硬件有⼀个潜在的优化(让硬件知道最⼤细分因⼦)。贫困大学生问题调查
D3D11硬件⽀持的最⼤细分因⼦是64.
什么是散文3 曲⾯细分阶段
作为程序员,我们⽆法控制曲⾯细分阶段,它是由硬件完成的,基于常量Hull着⾊器程序输出的细分因⼦对Patch进⾏细分,下⾯是⼀些基于不同因⼦细分的例⼦:
3.1 ⽅块patch的细分例⼦:
3.2 三⾓形patch的细分例⼦:
4 DOMAIN着⾊器
曲⾯细分阶段输出了所有新的顶点和三⾓形。DOMAIN着⾊器对每个新创建的顶点进⾏调⽤。当曲⾯细分开启的时候,顶点着⾊器运⾏与每个控制点,Hull着⾊器是每个细分patch的顶点着⾊器。Domain着⾊器中对每个细分完成的patch变换到其次裁切空间。
对于⽅块patch,Domain着⾊器输⼊细分因⼦(常量Hull着⾊器的输出),细分顶点位置(u, v)的坐标参数,所有从控制点hull着⾊器输出的控制点。Domain并不给你每个顶点的实际位置,⽽是patch空间的(u, v),顶点的位置通过双线性差值得到:
struct DomainOut
{
float4 PosH : SV_POSITION;
};
// The domain shader is called for every vertex created by the tessellator.
// It is like the vertex shader after tessellation.
[domain("quad")]
无痛人工流产术DomainOut DS(PatchTess patchTess,
float2 uv : SV_DomainLocation,
const OutputPatch<HullOut, 4> quad)
{
DomainOut dout;
// Bilinear interpolation.
float3 v1 = lerp(quad[0].PosL, quad[1].PosL, uv.x);
float3 v2 = lerp(quad[2].PosL, quad[3].PosL, uv.x);
float3 p = lerp(v1, v2, uv.y);
float4 posW = mul(float4(p, 1.0f), gWorld);
dout.PosH = mul(posW, gViewProj);
return dout;
}
三⾓形patch类似,只是坐标从(u, v)变为三维重⼼(u, v, w)坐标。修改为重⼼坐标系原因是贝塞尔三⾓形patches通过重⼼坐标系定义的。
5 细分⼀个平⾯⽅块
作为本章中的⼀个Demo,我们提交⼀个⽅块patch,然后根据和摄像机的距离进⾏细分,然后根据数学公式对顶点进⾏偏移(类似之
前“hills”Demo)。
顶点缓冲保存4个控制点,创建如下:

本文发布于:2024-09-21 20:31:30,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/14632.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:细分   控制点   顶点   阶段   输出   优化
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议