HLSL之Tessellation笔记1

前言

曲面细分着色器

在unity hdrp中,由于只支持hlsl因此,要实现tessellation的功能,不能与之前shader相同,需要自己手动重写tessellation,那么这部分的代码就主要为了完成在hlsl中重写曲面细分着色器。

资源来源于Microsoft的tessellation教程

pipeline
在这里插入图片描述
Hull shader
在这里插入图片描述

转换低程度的控制点为patch的控制点。并为tessellation阶段和domain阶段预处理每一个patch的数据。

在unityshader中,对应的hull脚本为:


            [maxtessfactor(MAX_TESSELLATION_FACTORS)]
            [domain("tri")]
            [partitioning("fractional_odd")]
            [outputtopology("triangle_cw")]
            [patchconstantfunc("HullConstant")]
            [outputcontrolpoints(3)]//输出的顶点数,如果需要临近节点,那么需要写多一些
            PackedVaryingsToDS MyHull(InputPatch<PackedVaryingsToDS, 3> input, uint id : SV_OutputControlPointID)
            {
                // Pass-through
                return input[id];
            }

注意看函数的输入输出。在设置中会要求设定输入输出的顶点数,这些顶点数能够决定是否需要临近顶点的数据,目前是3,那么就是不需要

  • shader的输入范围为1-32个控制点,
  • 输出1-32个控制点,忽略tessellation控制因子的值。输出的控制点将会提供给domain-shader stage,而patch constant将会提供给domain shader,而曲面细分因子将会提供给domain shader和tessellation shader
  • tessellation factor因子细分的程度
  • 函数前面的声明是为了提供给tessellation shader:控制点的数量、patch面、曲面细分(partitioning type)的类型.
  • 如果tessellation 因子被设置为0或者NAN,那么patch将会被剔除,tessellation stage将会运行失败,domain将会输出错误,细分网格输出为空。

在深层次,hull-stage只处理两部分:控制点的相位,patch-constant的相位(phase),在硬件中是并行处理。

  • 控制点相位操作读入每一个控制点,并且生成输出点(被controlpointID)定义
  • patch-constant相位操作生成角度细分因子和另一个patch constant。patch-constant phase在同一时间计算,并且只有只读属性。

hull shader的示例:

//前面是什么向tessellation shader的返回值
[patchsize(12)]
[patchconstantfunc(MyPatchConstantFunc)]
//函数体,包含范围的patch和tessellation factor
MyOutPoint main(uint Id : SV_ControlPointID,
     InputPatch<MyInPoint, 12> InPts)
{
     MyOutPoint result;
     
     ...
     //处理control point和patch constant
     //control-point phase 和patch-constant phase
     
     result = TransformControlPoint( InPts[Id] );

     return result;
}

unity hdrp中的hullconstant phase operation

TessellationFactors HullConstant(InputPatch<PackedVaryingsToDS, 3> input)
{
    VaryingsToDS varying0 = UnpackVaryingsToDS(input[0]);
    VaryingsToDS varying1 = UnpackVaryingsToDS(input[1]);
    VaryingsToDS varying2 = UnpackVaryingsToDS(input[2]);

    float3 p0 = varying0.vmesh.positionRWS;
    float3 p1 = varying1.vmesh.positionRWS;
    float3 p2 = varying2.vmesh.positionRWS;

    float3 n0 = varying0.vmesh.normalWS;
    float3 n1 = varying1.vmesh.normalWS;
    float3 n2 = varying2.vmesh.normalWS;

    // ref: http://reedbeta.com/blog/tess-quick-ref/
    //计算边缘因子
    // x - 1->2 edge
    // y - 2->0 edge
    // z - 0->1 edge
    // w - inside tessellation factor
    float4 tf = GetTessellationFactors(p0, p1, p2, n0, n1, n2);
    TessellationFactors output;
    output.edge[0] = min(tf.x, MAX_TESSELLATION_FACTORS);
    output.edge[1] = min(tf.y, MAX_TESSELLATION_FACTORS);
    output.edge[2] = min(tf.z, MAX_TESSELLATION_FACTORS);
    output.inside  = min(tf.w, MAX_TESSELLATION_FACTORS);

    return output;
}

在hlsl中tessellation是一个固定的阶段,也就是不能实现可编程。tessellation stage的任务是将hull stage传过来的domain(四边形、三角形、线)细分为跟小的对象。曲面细分器将每一个域的控制转换到归一化空间中[0-1],例如一个四边形域细分到一个单元四边形中。
tessellator这时候根据细分因子和分割类型将patch进行处理并输出处理后的uv坐标值。

tessellation分为两个阶段进行处理,
第一个阶段主要处理细分因子,避免因四舍五入出现的精度问题
第二阶段,根据细分的类型进行细分。生成点或者拓扑列表

Type of PartitioningRange
Fractional_odd[1…63]
Fractional_evenTessFactor range: [2…64]
IntegerTessFactor range: [1…64]
Pow2TessFactor range: [1…64]

最后一个阶段
Domain-shader stage

image

根据之前两个阶段生成的控制点数据、patch数据、patch固定值生成顶点位置。
domain-shader包括:

  • 一次调用读取一个细分阶段的坐标
  • 读取一次hull-shader的控制点
  • 输出顶点的坐标
  • 输入包括hull-shader的输出:控制点、patch constant数据以及细分因子。(细分因子包括细分阶段使用的原始数据)

经过domainshader处理后,shader输出几何着色器所需要的顶点信息。

需要 hlsl model 5版本的支持。

总结

hlsl中的细分曲面函数,分为三个部分
hull shader-》tessellation stage-》domain shader

hull shader, and domain shader are programable stage in render pipeline.The tessellation stage is a fixed function stage.

In hull stage, patch is inputted to operate and generate other patch and patch constant.

tessellation fixed rounding probrem of tessellation factors,and tiles a canonical domain in a normalized coordinate system.

Domain operate outputs of hull stage and tessellation stage , and output position of vertex

fork my github repository here

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值