图形学进阶——曲面细分与几何着色器

本文介绍了曲面细分着色器和几何着色器的原理与应用,包括曲面细分如何根据规则动态调整模型复杂度,以及几何着色器如何修改网格实现创新效果。通过实例演示了曲面细分在水面效果中的应用,以及未来可能的几何着色器实现。
摘要由CSDN通过智能技术生成

Tesselaation Shader & Geometry Shader

曲面细分着色与几何着色

百人计划学习地址:图形 3.3 曲面细分与几何着色器 大规模草渲染

一、曲面细分着色器

1. 原理

顾名思义,可以不断细化一个锐利的几何体,将它变成球体
也可以不断细分一条直线,向曲线逼近

2. 为什么要使用曲面细分

  • 直接使用顶点数更多的模型,会带来更高的性能消耗
  • 它可以根据自定义的规则来动态调整模型的复杂度,达成对应的效果

3. 应用

在这里插入图片描述

使用曲面细分是为了增加模型的细节,但是我们通常没必要在用户关注不到地方增加不必要的细节,因此我们会采取一些策略来得到动态的曲面细分因子:

  • 距离相机的远近:距离相机越远,需要越少的模型细节,而离相机越近,曲面细分的程度可以越高。
  • 屏幕空间的覆盖范围::我们可以估算出一个模型覆盖到的屏幕区域大小,覆盖区域越小,说明模型在屏幕上占比越小,此时可以使用低多边形模型,相反,覆盖区域越大,曲面细分的程度需要越高。
  • 三角面的朝向:三角面的朝向和观察方向的夹角越大,说明越靠近模型边缘(视觉上的轮廓边缘),而此时需要更高的模型精度,因此曲面细分程度要越高。
  • 表面粗糙度:粗糙表面相比平滑表面,需要更多的模型细节。例如视觉上粗糙不平的地面相比光滑的镜面,需要更多的模型细节来进行表现。

也可以与置换贴图结合:
在这里插入图片描述

二、几何着色器

1. 原理

可以将顶点变换为完全不同的图元,并且还能生成比原来更多的顶点

2. 为什么要使用几何着色器

因为可以修改网格(增删改模型的顶点及三角面等,所以可以实现非常多酷炫的效果

3. 应用

在这里插入图片描述

三、着色器的执行顺序

顶点着色器——》曲面细分着色器——》几何着色器——》片元着色器
在这里插入图片描述
注:

  • Hull Shader 细分控制着色器 和 Domain Shader 细分计算着色器是可编程的
  • Tessellation Primitive Generator不可编程

在OpenGL中HullShader 和DomainShader分别被简称:TCS和TES

四、TESS曲面细分工作原理

1. 输入与输出

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

2. 流程

① HuLL Shader
  • 决定细分的数量(设定Tessellation factor以及Inside Tessellation factor)
  • 对输入的Patch参数进行改变
② Tessellation Primitive Generator
  • 进行细分操作
③ Domain Shader
  • 对细分的点进行处理,从重心空间转换到屏幕空间

3. 关于HULL Shader各参数解析

  • Tessellation Factor:决定将一条边分成几部分
  • Inner Tessellation Factor:决定内部三角形怎么划分
    在这里插入图片描述

五、曲面细分Demo演示

先定义hullshader和domainshader的名称并应用对应的函数库

#pragma hull hullProgram
 #pragma domain ds
 #include "Tessellation.cginc"

Hull Shader代码:

struct TessVertex {
   
     float4 vertex : INTERNALTESSPOS;
     float3 normal: NORMAL;
     float4 tangent :TANGENT;
     float2 uv : TEXCOORD0;
 };
 //顶点着色器只传入对应的值
 TessVertex tessvert(appdata v)
 {
   
     TessVertex o;
     o.vertex = v.vertex;
     o.uv = v.uv;
     o.normal = v.normal;
     o.tangent = v.tangent;
     return o;
 }
 //图片结构体
 struct OutputPatchConstant 
 {
   
     float edge[3] : SV_TESSFACTOR;
     float inside : SV_INSIDETESSFACTOR;
 };
 OutputPatchConstant hsconst(InputPatch<TessVertex, 3> patch) {
   
     OutputPatchConstant o;
     //定义曲面细分的参数
     o.edge[0] = _TessellationFloat;
     o.edge[1] = _TessellationFloat;
     o.edge[2] = _TessellationFloat;
     o.inside = _TessellationFloat;
     return o;
 }
 [UNITY_domain("tri")]//确定图元,quad,triangle等
 [UNITY_partitioning("integer")]//拆分edge的规则,equal_spacing,fractional_odd,fractional_even
 [UNITY_outputtopology("triangle_cw")]
 [UNITY_patchconstantfunc("hsconst")]//一个patch一共有三个点,但是这三个点都共用这个函数
 [UNITY_outputcontrolpoints(3)]      //不同的图元会对应不同的控制点
 TessVertex hullProgram(InputPatch<TessVertex
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值