从0开始的技术美术之路(十五)曲面细分与几何着色器

本篇参考B站视频
“技术美术百人计划”·霜狼_may
《Shader入门精要》·冯乐乐女神著;
几何着色器·风宇冲
草地渲染·流朔
草渲染2
shader中随机数的生成法
碎片效果

本篇主要用于自我复习,其中会掺入一些个人观点,如有疑问或发现有什么错误,请多指教~
本篇内容主要包括:曲面细分着色器与几何着色器(缩写分别为TESS和GS);


写在前面

在正式开始之前,我觉得应该先回顾下渲染管线,尤其是这两个着色器的位置,因为在面试中也有被问到,如下图;

本篇要说的这两位都是在顶点着色器之后,裁剪之前,其中曲面细分着色器在几何着色器之前,两个都是可选的着色器,并不是必须要写的,且曲面细分着色器目前在手机上基本上没应用,而几何着色器最常用的则是用来渲染草地;
在这里插入图片描述


一.曲面细分着色器

1.它能干些啥

  • 海浪,雪地,下图中的右边通过曲面细分从平面变的有凹凸感
    在这里插入图片描述

  • 与置换贴图结合,置换贴图是移动了顶点位置来实现的,那么通过使用曲面细分着色器,我们可以增多模型顶点数量,从而使得效果看起来更好;

2.进一步细分曲面细分着色器

如下图,可以看到按顺序分为细分控制着色器(Hull Shader)Tessellation Primitive Generation细分计算着色器(Domain Shader)

曲面细分着色器,细分后的点,其空间位于重心空间,在细分计算着色器中,将其转换为我们要用的空间;
在这里插入图片描述

  • HULL Shader
    • 决定细分的数量(设定曲面细分因素【Tessellation factor】以及内曲面细分因素【Inside Tessellation factor】)
    • 对输入的Patch参数进行改变(根据需求要进行变换时)
  • Tessellation Primitive Generation
    • 进行细分操作
  • Domain Shader
    • 对细分后的顶点进行处理,将其从重心空间转换到屏幕空间

3.输入与输出

  • 输入
    Patch,可以看成是多个顶点的集合,包含每个顶点的属性(所有顶点共享),可以指定一个Patch包含的顶点数以及自己的属性;
  • 功能
    将图元细分(可以为三角形,矩形等)
  • 输出
    细分后的顶点

4.HULL Shader各参数解析

  • Tessellation Factor
    决定将一条边分成几个部分,它又三种分法,见下图:在这里插入图片描述

三者区别:
- equa_Spacing:将一条边等分,Subdivide参数是几就是几等分;
- fractional_even_Spacing:最小值为2,Subdivide参数向上取最近的偶数,将周长分为n-2的等长的部分,以及两端不等长的部分,目的是让细分更平滑;
- fractional_odd_Spacing :最小值为1,Subdivide参数向上取最近的奇数,将周长分为n-2的等长的部分,以及两端不等长的部分,目的是让细分更平滑;

  • Inner Tessellation Factor
    内部细分因素,当该参数为3时,无论上面的Tessellation Factor怎样去进行切分的,我们把三角形切分为三等分,然后分别找最近的两个切分的点,做其延长线,其焦点便是在新内部三角形的一个点;
    (概括下就是取边上点的垂线的延长线做交点,直至最后无交点或者交于中心一点)
    在这里插入图片描述

5.代码解析

  • 使用曲面细分着色器涉及到两个hull和domain两个shader,并且要引用其库文件;
    在这里插入图片描述

  • 不同于以往的shader代码,这里的vert函数并非顶点着色器,而是用来做空间转换用的,它应用于domain函数中;
    在这里插入图片描述

  • 定义宏,由于并非所有平台均支持曲面细分着色器,因而通过定义宏,以防出现bug红;

    在这里插入图片描述

  • 顶点着色器结构体定义,以及hullshader中用到的Patch属性,根据是三角形还是矩形的图元,edge[]里填3或4;
    在这里插入图片描述
    关于unity中导入四边面模型,查了下要求是模型在导出时是四边面,且勾选如下图的选项,即可 (但是我自己测试并无卵用,不知道哪里出错了)
    在这里插入图片描述

  • 接下来是顶点着色器,没啥好说的,由于在此之前已进行过空间转换,所以这里只是简单的传参;
    在这里插入图片描述

  • 接下来结合看两段,大致各段代码意思其实都如下图所示,其中中括号段落的第三条,用来表示图元的组装是按照顺时针还是逆时针,会影响最后显示有无正面剔除或者背面剔除;第四个中括号则是关联上面的一大段函数,规定曲面细分的属性;hullProgram则是hull函数,根据图元不同,InputPatch中的数字不同;

在这里插入图片描述

  • domain shader先定义图元,再进行空间转换,括号中的bary是重心空间(以重心为原点的坐标系)下的系数,用该系数与重心坐标还原到模型空间;
    在这里插入图片描述
  • 最后像素着色器
    在这里插入图片描述

参考着,写了一遍完整的,根据自己理解将其各部分说明了下,代码如下:

Shader "Unlit/sh_Tressla"
{
   
    Properties
    {
   
        _MainTex ("Texture", 2D) = "white" {
   }
		_TessellationUniform("细分参数",float)= 1.0
    }
    SubShader
    {
   
        Tags {
    "RenderType"="Opaque" }
        LOD 100

        Pass
        {
   
            CGPROGRAM

			#pragma hull myhull
            #pragma domain myds

			//接下来定义的顶点着色器并非如往常一样的
            #pragma vertex tessvert   
            #pragma fragment frag

            #include "UnityCG.cginc"

		    sampler2D _MainTex;
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值