技美知识学习3300:TESS and GS

学习教程来自:【技术美术百人计划】图形 3.3 曲面细分与几何着色器 大规模草渲染

Unity版本:Unity 2019.3.15f1


感谢老师的传道授业解惑,本篇用于总结复习和实践

1. 知识基础

TESS能做什么?

  1. 将曲面细分:直线逼近曲线、正方体细分成球体

  2. 增加凹凸感,与置换贴图结合使用
    在这里插入图片描述

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

对比图
  1. 优化:根据既定规则(如,距离)控制细分面数

GS能做什么?

  1. 几何动画:爆炸破碎效果

  2. 草地生成
    在这里插入图片描述

OpenGL中的着色顺序

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

2. TESS

#pragma hull hullProgram
#pragma domain ds

输入输出

输入Patch,将图元细分,输出细分后的顶点

流程

  1. HULL Shader:设定参数;对输入进行变化(若需要)
    在这里插入图片描述

  2. Tessellation Primitive Generation:细分操作

  3. Domain Shader:空间转换
    在这里插入图片描述

  4. 顶点替换的vert函数

在这里插入图片描述

使用切线空间矩阵将法线转换回世界空间

3. GS

#pragma geometry geo

输入输出

均为图元,输出的图元需要按顺序逐顶点构建

几何着色器函数

在这里插入图片描述

在切线空间中生成并转换到对象空间

4. TESS和GS结合使用

生成一个更加接近实际的模拟草地

几何着色器部分

  1. 生成一棵草

在这里插入图片描述

顶点从下往上添加,一共 SEGMENT * 2 + 1 个点
  1. 草的弯曲(bend)和朝向(wind+facing)
    在这里插入图片描述
最下边的2个点只考虑朝向
  1. 草的密度调整

在这里插入图片描述

在HullShader部分基于距离调整参数
  1. 效果

在这里插入图片描述

5. 课后作业

基于草的效果,尝试实现物体在草地上运动时产生的交互。

思路

这里使用了一个圆形小球作为运动的物体,小球下方的草地会被压平(height降低),未被压平但在小球周围的物体,会收到挤压向周围弯曲(facing和bend),并且这些与小球产生接触的草,收到风的影响会降低(wind)。


因此需要在几何着色器中重新计算以上的变化矩阵,基于当前小球在世界空间下的位置。

height

disFactor 为世界空间下的顶点与小球的距离

underFactor 为判断是否草在正下方

disFactor = compileFactor(_TestLocation,vWorldPos);
underFactor = disFactor < 0.6 ? 0.2 * disFactor : 1;

height = height * disFactor * underFactor;

facing

计算一个朝向,使周围的小草都朝向小球(只考虑XZ平面,从-Z方向开始超箭头方向一周,return的值从0变化到2PI,用arccos可求得)
在这里插入图片描述

float compileFacingFactor(float3 xPos, float3 yPos){
        float x = yPos.x-xPos.x;
        float z = yPos.z-xPos.z;
        float t = 0;
        if(x < 0){
            x = -x;
            z = -z;
            t = UNITY_PI;
        }
        return acos(dot(float3(0, 0, -1),normalize(float3(x, 0, z)))) + t;
}

facingFactor = compileFacingFactor(_TestLocation,vWorldPos);
facingRotationMatrixCus = AngleAxis3x3(facingFactor, float3(0, 0, 1)); 

bend

按距离增加了弯曲程度(不太严谨,应该离得越近越弯曲)

forwardFactor = 2;
bendRotationMatrixCus = AngleAxis3x3(forwardFactor * disFactor * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));

wind

越近受到风的影响越小

windFactor = 0.5;
windRotationCus = AngleAxis3x3(UNITY_PI * windSample * windFactor * disFactor, wind);

效果图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值