d3d12龙书学习之MiniEngine的最小化实现(十) 龙书第14章 曲面细分阶段

前言

dx12的渲染流水线如下,基本上起一个流水线的输出等于下一个流水线的输入

阶段名字可编程内容
输入装配器阶段 IA输入顶点、索引、拓扑结构
顶点着色器阶段 VS修改顶点数据,例如坐标转换
(可选)外壳着色器阶段 HS常量外壳着色器:输出曲面细分因子
(可选)外壳着色器阶段 HS控制点外壳着色器:设置曲面细分的参数
(可选)镶嵌化阶段不可编程
(可选)域着色器阶段 DS和没有开曲面细分的VS一样
(可选)几何着色器阶段 GS顶点的修改,可以添加删除
光栅化阶段 RS通过流水线的参数控制部分行为,背面剔除
像素着色器阶段 PS像素点的颜色控制
输出合并阶段 OM写入后台缓冲去,深度/模板测试,混合

曲面细分就包含3个阶段

  1. 外壳着色器
  2. 镶嵌化
  3. 域着色器

搞清楚这3个着色器的作用,就可以了。其他的就是一些流水线设置、IA的拓扑设置改下就可以了

常量外壳着色器

本着色器,必须输出的就是曲面细分因子,可以根据需要自己调整

// VS输出的顶点结构
struct VS_CONTROL_POINT_OUTPUT
{
	float3 vPosition : POSITION;    // 面片的顶点(模型坐标系顶点)
};

//  常量外壳着色器的输出结构,曲面细分因子
struct HS_CONSTANT_DATA_OUTPUT
{
	float EdgeTessFactor[4]			: SV_TessFactor; // 例如,对于四象限域,将为 [4]
	float InsideTessFactor[2]		: SV_InsideTessFactor; // 例如,对于四象限域,将为 Inside[2]
};

// 4个控制点的面片,也就是VS输出了4个顶点
#define NUM_CONTROL_POINTS 4

// 修补程序常量函数
HS_CONSTANT_DATA_OUTPUT CalcHSPatchConstants(
	InputPatch<VS_CONTROL_POINT_OUTPUT, NUM_CONTROL_POINTS> ip,	// VS输出的顶点数组
	uint PatchID : SV_PrimitiveID)																				// 面片ID
{
	HS_CONSTANT_DATA_OUTPUT Output;

	// 在此处插入代码以计算输出
	Output.EdgeTessFactor[0] = 
		Output.EdgeTessFactor[1] = 
		Output.EdgeTessFactor[2] = 
        Output.EdgeTessFactor[3] = 
        Output.InsideTessFactor[0] = 
		Output.InsideTessFactor[1] = 25; // 例如,可改为计算动态分割因子

	return Output;
}

控制点外壳着色器

[domain("quad")]                                // 四边形面片
[partitioning("integer")]                       // 细分模式 fractional_even fractional_odd
[outputtopology("triangle_cw")]                 // 通过细分创建的三角形顶点序
[outputcontrolpoints(16)]                       // 输出16个顶点
[patchconstantfunc("CalcHSPatchConstants")]     // 常量外壳着色器函数名
HS_CONTROL_POINT_OUTPUT main( 
	InputPatch<VS_CONTROL_POINT_OUTPUT, NUM_CONTROL_POINTS> ip, 	// VS输出的顶点数组
	uint i : SV_OutputControlPointID,								// 向外输出的点的ID
	uint PatchID : SV_PrimitiveID )									// 面片ID
{
	HS_CONTROL_POINT_OUTPUT Output;

	// 可以根据需要修改顶点的坐标,每个输出点都会调用一次。
	Output.vPosition = ip[i].vPosition;

	return Output;
}

域着色器

[domain("quad")]
DS_OUTPUT main(
	HS_CONSTANT_DATA_OUTPUT input,      // 曲面细分因子
	float2 domain : SV_DomainLocation,  // 新插入顶点的uv坐标(基于面片内部)
	const OutputPatch<HS_CONTROL_POINT_OUTPUT, NUM_CONTROL_POINTS> patch)   // 原始面片的N个点
{
	DS_OUTPUT Output;

    ...

	return Output;
}

对于曲面细分之后的每一个顶点都会执行一次域着色器。其中那个uv坐标是基于面片内部的。
patch包含所有细分之后的顶点。
操作起来就跟VS一样。可以修改顶点的位置,法向量等等。

看下龙书的结果

本章内容还是比较简单的,渲染对象什么的,自行添加就好。注意PSO以及IA阶段设置拓扑结构为面片。
直接来看下本章的内容:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值