Directx11教程(59) tessellation学习(1)
原文:Directx11教程(59) tessellation学习(1)
在D3D11管线中,新增加了3个stage, Hull shader, Tessellator, Domain shader,用来实现细分操作,就是在gpu中把低细节的表面细分成高细节的体元。在gpu中把低模通过tessellation转化为高模,在获得高细节模型的同时,可以有效降低把顶点数据从system memory传到 video memory的带宽消耗。
下面我们看看这三个阶段到底做些什么,输入是什么,输出是什么?先画一张图。

1、Hull shader阶段
Hull shader阶段可以分成两个独立的阶段,它们是并行执行的。
第一个阶段是per control points执行的, 在这个阶段对patch中的每个控制点,输出对应的控制点。所谓patch,简单理解就是带控制点的体元,比如一个三角形,它的三个顶点是控制点,那么这个三角形就是有3个控制点的patch。当然,在Hull shader中,我们还可以对输入的控制点进行转化操作,生成新的控制点,比如输入的3个控制点,输出6个控制点。注意:输入或者输出的控制点数量是1~32。
第二个阶段就是patch常量阶段,这时HullShader会调用一个const data函数,这个函数主要产生tessellation factor,这些factor决定在TS阶段如何细分当前的patch。
另外,在Hullshader阶段还会指定一些TS阶段使用的Tessellation模式,比如细分的patch是三角形(拓扑模式),partition mode(选择什么细分算法)是HS_PARTITION等。
下面看一段Hull shader的代码:
struct HullInputType
{
float3 position : POSITION;
float4 color : COLOR;
};
struct ConstantOutputType
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
struct HullOutputType
{
float3 position : POSITION;
float4 color : COLOR;
};
// Patch 常量函数,决定tessellation因子,每个patch执行一次,所以是per patch的,不是per控制点的
ConstantOutputType ColorPatchConstantFunction(InputPatch<HullInputType, 3> inputPatch, uint patchId : SV_PrimitiveID)
{
ConstantOutputType output;
//设置三条边的细分因子
output.edges[0] = tessellationAmount;
output.edges[1] = tessellationAmount;
output.edges[2] = tessellationAmount;
//设置三角形内的细分因子
output.inside = tessellationAmount;
return output;
}
//注意输入控制点数量要和 IASetPrimitiveTopology()函数中一致
//本例子中,都为3 INPUT_PATCH_SIZE
// The hull shader is called once per output control point, which is specified with
// outputcontrolpoints. For this sample, we take the control points from the vertex
// shader and pass them directly off to the domain shader. In a more complex scene,
// you might perform a basis conversion from the input control points into a Bezier
// patch, such as the SubD11 Sample of DirectX SDK.
// The input to the hull shader comes from the vertex shader
// The output from the hull shader will go to the domain shader.
// The tessellation factor, topology, and partition mode will go to the fixed function
// tessellator stage to calculate the UVW and domain points
[domain("tri")] //Triangle domain for our shader
[partitioning("integer")] //Partitioning type according to the GUI
[outputtopology("triangle_cw")] //Where the generated triangles should face
[outputcontrolpoints(3)] //Number of times this part of the hull shader will be called for each patch
[patchconstantfunc("ColorPatchConstantFunction")] //The constant hull shader function
HullOutputType ColorHullShader(InputPatch<HullInputType, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
{
HullOutputType output;
//设置控制点
output.position = patch[pointId].position;
// 输出颜色为输入颜色
output.color = patch[pointId].color;
return output;
}
2. Tessellator阶段
Tessellator是一个固定管线阶段,它的主要功能就是细分一个domain(三角形, 四边形或线),把它们细分成很多小的物体,比如三角形,四边形或者线。
在细分时,tessellator会在一个归一化的坐标系统中处理patch,比如输入是一个quad(四边形),但这个quad先要映射到一个单位为1的正方形上,然后tessellator会对这个正方形进行细分操作。
Tessellator是per patch操作的,Hull shader阶段传入的Tess Factor决定细分多少次,而Hull shader阶段传入的partitioning则决定选用何种细分算法。Tessellator输出为u,v, {w}坐标以及细分后domain的拓扑信息。
3. Domain Shader阶段
Domain Shader 阶段会根据TS阶段生成的u,v , {w}坐标以及HS阶段传入的控制点在patch中生成细分后顶点的位置。
Domain shader是per vertex的,对于TS中每个细分产生的顶点,它都要调用一次。它的输入参数除了u,v,{w}坐标及控制点以外,还有const data,比如Tess factor等。
下面是一段Domain shader的代码:
struct ConstantOutputType
{
float edges[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
struct HullOutputType
{
float3 position : POSITION;
float4 color : COLOR;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
//每个细分后的顶点调用一次
[domain("tri")]
PixelInputType ColorDomainShader(ConstantOutputType input, float3 uvwCoord : SV_DomainLocation, const OutputPatch<HullOutputType, 3> patch)
{
float3 vertexPosition;
PixelInputType output;
//基于重心坐标的顶点生成
vertexPosition = uvwCoord.x * patch[0].position + uvwCoord.y * patch[1].position + uvwCoord.z * patch[2].position;
// 计算新的顶点在世界坐标系中的位置
output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
//新生成顶点颜色也为各个控制点颜色组合
output.color = uvwCoord.x * patch[0].color + uvwCoord.y * patch[1].color + uvwCoord.z * patch[2].color;
return output;
}
Directx11教程(59) tessellation学习(1)的更多相关文章
- Directx11教程(64) tessellation学习(6)-PN Triangles
原文:Directx11教程(64) tessellation学习(6)-PN Triangles 前面我们用tessellation细分三角形或者四边形,产生的细分点都是在三角形或四边形 ...
- Directx11教程(63) tessellation学习(5)
原文:Directx11教程(63) tessellation学习(5) TS中生成细分后顶点的u,v,{w}坐标,我们根据控制点和u,w,{w}坐标生成新的顶点位置,在前面四边形的细分 ...
- Directx11教程(62) tessellation学习(4)
原文:Directx11教程(62) tessellation学习(4) 现在看看四边形在不同tess factor时,四边形细分的细节,下图是tess factor1-8时候的细分.te ...
- Directx11教程(61) tessellation学习(3)
原文:Directx11教程(61) tessellation学习(3) 现在我们看看在不同tess factor的情况下,三角形是如何细分的?(这儿三条边和内部tess factor值是 ...
- Directx11教程(60) tessellation学习(2)
原文:Directx11教程(60) tessellation学习(2) 本教程中,我们开始tessellation编程,共实现了2个程序,第一个tessellation程序,是对一个三 ...
- Directx11教程(16) D3D11管线(5)
原文:Directx11教程(16) D3D11管线(5) 本章我们学习VS中具体做些什么事情? 首先再看看我们的VS shader代码: Clolor.vs - PixelInputType Col ...
- Directx11教程(15) D3D11管线(4)
原文:Directx11教程(15) D3D11管线(4) 本章我们首先了解一下D3D11中的逻辑管线,认识一下管线中每个stage的含义. 参考资料:http://fgiesen.wordpress ...
- Directx11教程(66) D3D11屏幕文本输出(1)
原文:Directx11教程(66) D3D11屏幕文本输出(1) 在D3D10中,通过ID3DX10Font接口对象,我们可以方便的在屏幕上输出文字信息,一个DrawText函数就能解决所 ...
- Directx11教程(56) 建立一个skydome
原文:Directx11教程(56) 建立一个skydome 本章建立一个skydome(天空穹),主要学习如何使用cube mapping. cube map就是把六张纹理当作 ...
随机推荐
- VitualBox虚拟机安装CentOS, shell模式与图形化界面的相互切换
方法一:永久切换 # vi /etc/inittab 编辑 init 5 为 init 3,重启就自动进入控制台方式:反之桌面模式 方法二:当前有效 桌面模式切换shell模式:Ctrl + Alt ...
- ConnectionString连接字符串-密码丢失的解决方法
今天遇到一个问题,EF,asp.net web端登录成功,退出,再登录就异常了, 登出成功时, EF 中 dbcontext.Database.Connection.ConnectionString ...
- 五、Hive-HBase接口表性能分析
设想: Hbase不支持join,不能做复杂统计类: Hive可以. Hive-hbase接口表岂不两全其美? 用户画像表有300个字段,每天都使用: 1.在业务系统里实时根据uid调取用户的画像信息 ...
- JQuery学习:jquery对象和js对象区别和转换
JQuery对象与JS对象区别与转换 1.JQuery对象在操作时,更加方便 2.JQuery对象和js对象方法不通用 3.两者相互转换 * jq -- > js:jq对象[索引] 或者 ...
- ECS应用管理最佳实践
前言 即使在CloudNative发展如火如荼的当下,ECS应用(直接将应用部署在ECS上,不使用容器)仍然占了相当大的比重,原因主要在于相对容器化应用,ECS应用由于不需要容器的运行时环境和类似K8 ...
- bzoj 2503 相框——思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2503 我也知道应该只关注度数. #include<iostream> #incl ...
- bzoj 1093 [ZJOI2007]最大半连通子图——缩点+拓扑
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1093 缩点+拓扑,更新长度的时候维护方案数. 结果没想到处理缩点后的重边,这样的话方案数会算 ...
- H5C3--盒子模型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- UOJ#422. 【集训队作业2018】小Z的礼物
#422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...
- 你需要一个新的model实体的时候必须new一个.奇怪的问题: 使用poi解析Excel的把数据插入数据库同时把数据放在一个list中,返回到页面展示,结果页面把最后一条数据显示了N次
数据库显示数据正常被插 插入一条打印一次数据,也是正常的,但是执行完,list就全部变成了最后一条数据.很奇怪 单步调试 给list插入第一条数据 model是6607 连续插了多条数据都是6607 ...