[学习记录]Unity-Shader-几何着色器

        几何着色器是可编程渲染管线中的一个可选阶段,位于顶点着色器之后和片段着色器之前。其核心能力在于动态生成和操作几何体图元。

一.图元

        了解图元是理解几何着色器的基础和前提,因为几何着色器的工作就是接收图元,然后输出图元

几何着色器是以图元为单位工作的:

输入是图元: 几何着色器不像顶点着色器那样单独处理每个顶点。它的输入是一个完整的图元。这意味着它一次性接收构成一个点、一条线或一个三角形的所有顶点数据。例如,当它接收一个三角形时,它会同时获得这个三角形的三个顶点及其所有属性。

输出是图元: 同样地,几何着色器的输出也不是孤立的顶点,而是组织成完整图元(点、线或三角形)的顶点流。

1.什么是图元?

在计算机图形学中,图元是构成任何 3D 几何体的最基本构建块。 它们是图形硬件能够直接理解和渲染的最小单位。

主要的三种基本图元类型是:

点 (Points): 最简单的图元,由一个顶点定义。它没有面积或体积,只代表一个空间位置。

线 (Lines): 由两个顶点定义,连接这两个顶点形成一条线段。它只有长度,没有面积或体积。

三角形 (Triangles): 由三个顶点定义,这三个顶点构成一个平面多边形。

2.图元拓扑类型

在应用阶段,CPU需要向GPU提交一系列数据和命令供其渲染。
        应用阶段最重要的任务是输入装配(input assembler)。输入装配阶段会从显存中读取几何数据(顶点和索引),再将它装配为几何图元(geometry primitive)
        可是,单凭顶点和索引数据,GPU无法知道顶点究竟如何组成几何图元。例如,我们应将顶点2个一组解释成线段,还是3个一组解释为三角形呢?对此,我们需要通过指定图元拓扑(primitive topology) 来告诉GPU如何利用顶点数据来表示几何图元。

在DirectX中,基础图元拓扑类型有以下五种:点列表(point list)线条带(line strip)线列表(line list)三角形带(triangle strip)三角形列表(triangle list)

      

3.图元与拓扑的关系

拓扑 (Topology) 是指几何对象的连接性 (Connectivity)结构关系,它描述了点、边、面之间是如何相互连接的,而不关注它们在空间中的具体位置或形状。

图元就是拓扑的基本表现形式:

顶点是拓扑的基本元素: 它们是构建所有图元的基础。

图元类型定义了局部拓扑:

点图元: 拓扑上是孤立的顶点。线图元: 拓扑上是两个顶点通过一条边相连。三角形图元: 拓扑上是三个顶点通过三条边相连,形成一个面。

多个图元组合形成复杂拓扑

二.几何着色器是什么

        几何着色器是可编程渲染管线中的一个可选阶段,位于顶点着色器之后和片段着色器之前。其核心能力在于动态生成和操作几何体图元。特点如下:

1.接收一个完整的图元(Primitive)作为输入: 它可以是点、线或三角形。

2.动态生成新的图元: 根据输入,它可以决定输出零个、一个或多个新的点、线或三角形。

3.修改图元类型: 例如,将一个点扩展成一个四边形(公告板),或者将一个线段扩展成一个带状物体。

几何着色器位于几何处理阶段的可选顶点处理阶段。

三.几何着色器的核心概念

几何着色器的一般格式:

[maxvertexcount(N)]
void geom(triangle Attributes input[3], inout TriangleStream<Varyings> stream)
{}

1.最大顶点数量

        [maxvertexcount(N)] 用来指定几何着色器单词调用所输出的顶点数量最大值。其中,N是几何着色器单次调用所输出的顶点数量最大值。几何着色器每次输出的顶点个数都可能不同,但是这个数量却不能超过之前定义的最大值。
        出于对性能方面的考虑,我们应当令maxvertexcount的值尽可能小。线管资料显示,GS每次输出的标量数量在1-20时,它将发挥出最佳的性能;而当27-40时,它的性能将下降到峰值性能的50%。

2.输入图元

几何着色器最根本的特点是它处理的单位是完整的图元。

顶点着色器中的输出结构需要与几何着色器的输入结构对应一致

你的顶点着色器中返回的是什么类型,几何着色器的输入结构就是什么类型。

1.HLSL语法定义

point YourAttributesStruct input[1]
line YourAttributesStruct input[2]
triangle YourAttributesStruct input[3]

通过几何着色器函数的第一个参数来指定输入的图元类型。

2.输入图元类型

(1)点 (Point)

由一个顶点构成。

HLSL 定义:point InputStruct input[1] ,input[1]表示一个包含单个元素的数组。

input[0]即可访问该点的顶点数据。

何时使用: 当你希望将模型中的离散点(例如粒子系统的粒子、点云数据、骨骼关节)扩展成更复杂的几何体时(例如,将点变成公告板四边形)。

(2)线 (Line)

由两个顶点构成,连接形成一条线段。

HLSL 定义: line InputStruct input[2]

input[0] 和input[1]分别访问线段的起始点和结束点的顶点数据。

何时使用: 当你希望将模型中的线段(例如,线框模型、角色骨骼连接线、某些头发渲染中的发束)加粗、变成带状几何体或在其上生成其他结构时。

(3)三角形 (Triangle)

由三个顶点构成,形成一个平面。

HLSL 定义: triangle InputStruct input[3]

input[0],input[1],input[2] 分别访问三角形的三个顶点的顶点数据。

何时使用: 这是最常见的输入类型,当你希望从网格的面(例如,头皮表面、地形面)生成额外的几何体时(如 Fin Fur 毛发、草地、树叶等)。

3.输出图元流

        几何着色器不像顶点着色器那样直接return一个顶点,它通过向一个输出流 (Stream) 中Append 顶点来构建新的图元。这个流会累积你生成并追加(Append)入流的顶点,并根据流的类型自动将它们组织成图元。

        这里OutputStruct必须是几何着色器传递给片段着色器的数据结构。它至少需要包含SV_POSITION语义的裁剪空间位置。

1.HLSL语法定义

inout PointStream<YourOutputStruct> stream
inout LineStream<YourOutputStruct> stream
inout TriangleStream<YourOutputStruct> stream

        在HLSL中,几何着色器函数的第二个参数是标有inout修饰符的流类型(stream type) 。流类型存有一系列顶点,它们定义了几何着色器输出的几何图形。
流类型的本质是一种模板类型(template type),其模板参数用以指定输出顶点的具体类型。

2.输出图元流类型

(1)PointStream<OutputStruct>

功能: 每次调用Apped()都会向流中添加一个顶点,并将其作为独立的点图元输出。

何时使用: 当希望从输入的几何体中提取或生成离散的点时。

(2)LineStream<OutputStruct>

功能: 每两次调用Append()会创建一个新的线段图元。如果连续Append多个顶点,它们将形成一个线段条带 (Line Strip),每条新线段都会重用前一条线段的最后一个顶点。

何时使用: 当你希望从输入的几何体中生成线段、轮廓线或细长的带状物时。

示例:stream.Append(v3): 输出线段 (v2, v3)。

(3)TriangleStream<OutputStruct>

功能: 每三次调用Append()会创建一个新的三角形图元。如果连续Append多个顶点,它们将形成一个三角形条带 (Triangle Strip),这意味着每个新三角形都会重用前两个三角形的顶点。

何时使用: 这是最常用的输出类型,当你希望从输入的图元中生成面片(例如毛发、草叶、将点转换为四边形)。

4.关键函数

(1)stream.Append(OutputStruct vertexData)

作用: 将几何着色器的输出数据追加到一个现有的图元流中。

参数: 接受一个OutputStruct类型的数据,其中包含了新生成顶点在裁剪空间的位置 (SV_POSITION),以及该顶点需要传递给片段着色器的所有其他属性(如 UV、法线、颜色等)。

工作机制: GPU 会将这个顶点数据暂存起来,直到凑够构成一个完整图元所需的顶点数量(例如,对于TriangleStream需要三个顶点)。一旦凑够,该图元就会被发送到渲染管线的下一个阶段(光栅化器)。

消耗预算: 每次调用Append()都会消耗几何着色器[maxvertexcount(N)] 预算中的一个顶点。

(2)stream.ResatrtStrip()

作用: 仅用于LineStream和TriangleStream,强制结束当前的基元条带,开始一个新的条带。如果当前的条带没有足够的顶点被追加出来以填满基元拓扑结构,那么末端的不完整基元将被丢弃。

何时使用: 当你需要生成多个不连续的图元时。

例如: 如果你输入一个三角形,希望输出三个独立的四边形(而不是一个由 12 个顶点组成的连续三角形条带),那么在每生成一个四边形所需的四个顶点后,就需要调用 stream.ResatrtStrip()。这样下一个四边形的顶点将从一个新的条带开始,而不会与前一个四边形连接。

工作机制: 告诉GPU已经完成了当前这个条带的图元,请准备好接收下一个完全独立的图元序列。

参考文章

1.(90 封私信 / 80 条消息) Unity几何着色器详解 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87580.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87580.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Paimon 布隆过滤器索引

布隆过滤器原理布隆过滤器的最优参数推导是其理论核心&#xff0c;理解了这个过程&#xff0c;就能明白 BloomFilter64 构造函数里计算公式的由来了。下面我们一步步来推导。首先&#xff0c;我们定义几个关键变量&#xff1a;n: 预估要插入的元素数量 (对应代码中的 items)。m…

Python-GUI-wxPython-布局

1 需求 2 接口 wx.Sizer().Add() proportion&#xff08;比例&#xff09;参数是一个整数&#xff0c;用于指定当父布局管理器的空间有剩余时&#xff0c;被添加的对象&#xff08;这里是 general_sizer 及其包含的组件&#xff09;在布局方向上可以占据的额外空间的比例。 当…

springboot 链路追踪实现

traceid实现 需要依赖<dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.14.5</version></dependency>public class TraceIdContext {private static final String …

JavaEE初阶第七期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(五)

专栏&#xff1a;JavaEE初阶起飞计划 个人主页&#xff1a;手握风云 一、死锁 1.1. 死锁的概念 死锁是指两个或多个并发进程&#xff08;或线程&#xff09;在执行过程中&#xff0c;因争夺资源而造成的一种互相等待的现象。如果没有外力作用&#xff0c;这些进程将永远无法继…

黑暗中的爆破(船讯网Ais爬虫暨爬虫实战js逆向学习经验分享)

事先声明:本文章所获得的信息均通过合法手段获得(本人为政府部门工作,爬虫行为均经过授权),爬虫需遵守各项法律法规,不该爬取的信息不爬。 最近因为做博士毕业设计需要用到ais信息,但在船讯网爬取ais的时候遇到了问题,因为之前爬取的人太多,所以网站加上了反爬措施,c…

代码混淆的步骤

在 Android 开发中&#xff0c;代码混淆&#xff08;ProGuard/R8&#xff09;是保护代码安全和缩减应用体积的关键步骤。以下是详细的混淆流程和优化策略&#xff1a; 一、基础混淆步骤 1. 启用混淆 在 build.gradle 中配置&#xff1a; android {buildTypes {release {mini…

分布式集合通信--学习笔记

分布式集合通信一 基础概念 分布式系统模型 节点与进程模型 多机多卡、多机多进程通信模式 同步 、异步 集合通信定义 点对点通信 vs 集合通信 点对点通信 定义 &#xff1a;两个节点之间的直接数据传输&#xff0c;通常基于专用链路或网络路径通信范围&#xff1a;仅涉及两…

工业显示器五大品牌推荐及分析

在智能制造与工业自动化中&#xff0c;工业显示器扮演着至关重要的角色&#xff0c;最近好多朋友问我有没有什么卖工业显示的厂家推荐。那今天我为大家整理了5个工业显示器厂家品牌推荐&#xff0c;希望可以帮助您挑选到合适的工业显示器一、佳维视&#xff08;JAWEST&#xff…

ComfyUI工作流:一键换背景体验不同场景

换背景效果展示 在图像编辑领域&#xff0c;背景替换是提升作品视觉效果与创意表达的重要手段。魔多 AI 社区推出的 “一键换背景” ComfyUI 工作流&#xff0c;凭借先进的 AI 技术与极简操作流程&#xff0c;为用户提供了高效、精准的背景替换解决方案。本文将从技术原理、功能…

图像旋转:从原理到 OpenCV 实践

在图像处理领域&#xff0c;图像旋转是一项基础且重要的操作。它不仅可以改变图像的方向&#xff0c;还在许多计算机视觉任务中发挥着关键作用&#xff0c;比如目标检测、图像配准等。本文将深入探讨图像旋转的原理&#xff0c;并结合 OpenCV 库提供具体的实现代码。 一、图像…

微服务架构下的抉择:Consul vs. Eureka,服务发现该如何选型?

微服务架构下的抉择&#xff1a;Consul vs. Eureka&#xff0c;服务发现该如何选型&#xff1f; 引言 想象一下&#xff0c;我们正在构建一个大型电商平台。在“双十一”大促期间&#xff0c;流量洪峰涌入&#xff0c;订单服务、商品服务、用户服务等都需要弹性伸缩&#xff…

基于Java+SpringBoot的宠物爱心组织管理系统

源码编号&#xff1a;S572 源码名称&#xff1a;基于SpringBoot的宠物爱心组织管理系统 用户类型&#xff1a;双角色&#xff0c;用户、管理员 数据库表数量&#xff1a;15 张表 主要技术&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven 运行环境&#xff1a;Windo…

数字样机:改写卫星物联网的研制范式

01. 卫星物联网&#xff1a;技术边界的自然延伸 随着物联网在城市、工业、农业等领域的广泛部署&#xff0c;万物互联的愿景正在不断逼近技术的边界。尤其是在海洋、沙漠、高原、边远山区等传统通信网络难以覆盖的区域&#xff0c;人们对无盲点物联网连接的需求日益增强。这一…

springsecurity---使用流程、加密机制、自定义密码匹配器、token字符串生成

目录 权限控制 相关框架 SpringSecurity springsecurity使用流程 1、搭建环境实现默认用户名和密码登录 2、使用数据库表中定义好的用户名和密码访问实现等值密码匹配 1&#xff09;sql文件 2)搭建jdbc或者mybatis或者mybatis-plus环境 3&#xff09;配置mybatis-plus环…

在 Ubuntu 22.04 上使用 Minikube 部署 Go 应用到 Kubernetes

文章目录 环境说明目标步骤与问题解决1. 构建 Go 应用和 Docker 镜像问题 1&#xff1a;Go 依赖下载卡住问题 2&#xff1a;Docker 镜像拉取失败 2. 设置 Minikube 集群安装 Minikube问题 3&#xff1a;Minikube 启动失败问题 4&#xff1a;Minikube 镜像拉取失败 3. 部署 Kube…

Android Studio-Git的使用指南

一、git的基本使用流程 git clone 克隆远程资源到本地目录&#xff0c;作为工作目录&#xff1b;然后在本地的克隆目录上添加或修改文件&#xff1b;如果远程修改了&#xff0c;需要同步远程的内容&#xff0c;直接git pull就可以更新本地的文件&#xff1b;本地在修改之后&…

【github】想fork的项目变为私有副本

在 GitHub 上&#xff0c;所有的 fork 都会继承其上游仓库&#xff08;upstream&#xff09;的可见性&#xff08;visibility&#xff09;设置&#xff1a; 可见性继承 如果你 fork 的原仓库是 public&#xff0c;那么你的 fork 也必须是 public。如果原仓库是 private&#xf…

微软发布新一代存储优化型虚拟机:Azure Laosv4、Lasv4 和 Lsv4 系列

微软宣布&#xff0c;全新一代存储优化型虚拟机——Azure Laosv4、Lasv4 和 Lsv4 系列已正式面世。 与前一代虚拟机系列相比&#xff0c;全新的 L 系列虚拟机实现了重大突破。它支持高达 23TB 的本地 NVMe SSD&#xff0c;在 CPU、网络以及远程存储性能方面均有显著提升。该系…

python调用pybind11导出的pyd,出现UnicodeDecodeError

python调用pybind11导出的pyd&#xff0c;出现UnicodeDecodeError 1. 问题描述 举个例子&#xff0c;当有以下C代码以及Pybind11的绑定代码时&#xff0c;在python访问包含中文的Name和Value会有UnicodeDecodeError的异常&#xff01; class VxUserProp{public:VxUserProp();…

MySQL别名在GROUP BY中的使用规则

-- 设置变量&#xff1a;SET earliest_date ... 用于定义并赋值一个用户变量 earliest_date。 -- 用户定义的变量必须以 符号开头&#xff0c;例如 earliest_date。 -- 符号是MySQL中用户变量的标识符&#xff0c;用于区分系统变量和用户变量。 SET earliest_date (SELECT …