Direct3D 12——几何着色器——几何着色器概念

news2024/10/2 14:29:11

几何着色器

几何着色器这个可选阶段便位于顶点着色器与像素着色器之间。几何着色器所输出的图元由顶点列表定义而成。在退岀几何着色器时,必将顶点的位置变换到齐次 裁剪空间。换言之,经过几何着色器阶段的处理后,我们就得到了位于齐次裁剪空间中由一系列顶点所 定义的多个图元。这些顶点会同样历经投影(齐次除法)与光栅化等后续步骤。

几何着色器的一般编写格式:

[maxvertexcount(N)]
void ShaderName (PrimitiveType InputVertexType InputName[NumElements],
inout StreamOutputObject<OutputVertexType> OutputName)
(
//几何着色器的具体实现
}

我们必须先指定几何着色器单次调用所输出的顶点数量最大值(每个图元都会调用一次几何着色器, 走一遍其中的处理流程)。对此,可以使用下列属性语法来设置着色器定义之前的最大顶点数量:

[maxvertexcount(N)]

其中,N是几何着色器单次调用所输出的顶点数量最大值。几何着色器每次输岀的顶点个数都可能各不相同,但是这个数量却不能超过之前定义的最大值。出于对性能方面的考量,我们应当令 maxvertexcount的值尽可能地小。在GS(即几何着色器的缩写,geometry shader )每次输出的标量数量在1〜20时,它将发挥出最佳的性能;而当GS每次输出的标量数量保持在 27〜40时,它的性能将下降到峰值性能的50% 。每次调用几何着色器所输岀的标量个数为: maxvertexcount与输出顶点类型结构体中标量个数的乘积L。

几何着色器输入参数必须是一个定义有特定图元的顶点数组——点应输入一个顶点、线条要 输入两个顶点、三角形需输入3个顶点、线及其邻接图元为4个顶点、三角形及其邻接图元则为6个顶 点。几何着色器的输入顶点类型即为顶点着色器输出的顶点类型(例如Vertex0ut)。输入参数一定要 以图元类型作为前缀,用以描述输入到几何着色器的具体图元类型。该前缀可以是下列类型之一:

  1.point:输入的图元为点。
  2.line:输入的图元为线列表或线条带。
  3.triangle:输入的图元为三角形列表或三角形带。
  4.lineadj :输入的图元为线列表及其邻接图元,或线条带及其邻接图元。
  5.triangleadj :输入的图元为三角形列表及其邻接图元,或三角形带及其邻接图元。

向几何着色器输入的数据必须是完整的图元(例如组成线条的两个顶点、构成三角形的3个 顶点等)。因此,几何着色器并不会区分输入的图元究竟是列表结构(list)还是带状结构 (strip )o举个例子,若绘制的图元实际上是三角形带,但几何着色器仍会把三角形带视作多 个三角形并分别进行单独的处理,即将每个三角形的3个顶点作为其输入数据。绘制带状结 构的过程中会产生额外的开销,因为多个图元所共用的顶点在几何着色器中会被处理多次。

输岀参数一定要标有inout修饰符。另外,它必须是一种流类型(stream typeo即某种类型的流输 出对象)。流类型存有一系列顶点,它们定义了几何着色器输出的几何图形。几何着色器可以通过内置方法Append向输岀流列表添加单个顶点:

void StreamOutputObject<OutputVertexType>::Append(OutputVertexType v);

流类型本质上是一种模板类型(template type),其模板参数用以指定输岀顶点的具体类型(如 GeoOut )。流类型有如下3种。

1.PointStream<OutputVertexType>: 一系列顶点所定义的点列表。
2.LineStream<OutputVertexType>: 一系列顶点所定义的线条带。
3.TriangleStream<OutputVertexType>: 一系列顶点所定义的三角形带。

几何着色器输岀的多个顶点会构成图元,图元的输岀类型由流类型(即Pointstream. Linestream与TriangleStream )来指定。对于线条与三角形来说,几何着色器输岀的对应图元必 定是线条带与三角形带。而线条列表与三角形列表可借助内置函数Restartstrip来实现:

void StreamOutputObject<OutputVertexType>::Restartstrip();
mShaders["treeSpriteGS"] = d3dUtil::CompileShader(L"Shaders\\TreeSprite.hlsl", nullptr, "GS", "gs_5_0");

下列几何着色器详细地展示了 Append与Restartstrip方法的调用过程。此示例会将输入的三 角形进行细分,并输出细分后的4个小三角形:
在这里插入图片描述

struct VertexOut
{
    float3 PosL     : POSITION;
    float3 NormalL  : NORMAL;
    float2 Tex      : TEXCOORD;
};
struct GeoOut
{
	float4 PosH    : SV_POSITION;
    float3 PosW    : POSITION;
    float3 NormalW : NORMAL;
    float2 Tex    : TEXCOORD;
    float  FogLerp  : FOG;
};

void Subdivide(VertexOut inverts[3], out VertexOut outVerts[6])
{
          //         1
          //         *
          //        / \
          //       /   \
          //   m0*-------*m1
          //    / \    / \
         //    /   \  /   \
         //   *-----*------*
         //   0     m2      2
         
        VertexOut m[3];
        
      //计算三角形边上的中点
     m[0].PosL = 0.5f*(inverts[0].PosL+inVerts[1].PosL); 
     m[l].PosL = 0.5f*(inverts[1].PosL+inVerts[2].PosL);
     m[2].PosL = 0.5f*(inverts[2].PosL+inVerts[0].PosL);

      //把顶点投影到单位球面上
     m[0].PosL = normalize(m[0].PosL); 
     m[1].PosL = normalize(m[1].PosL); 
     m[2].PosL = normalize(m[2].PosL);

     //求出法线
     m[0].NormalL = m[0].PosL;
     m[1].NormalL = m[1].PosL;
     m[2].NormalL = m[2].PosL;
     
     //对纹理坐标进行插值
     m[0].Tex = 0.5f*(inverts[0].Tex+inVerts[1].Tex);
     m[1].Tex = 0.5f*(inverts[1].Tex+inVerts[2].Tex);
     m[2].Tex = 0.5f*(inverts[2].Tex+inVerts[0].Tex);

     outVerts[0] = inVerts[0];
     outVerts[1] = m[0];
     outVerts[2] = m[2];
     outVerts[3] = m[1];
     outVerts[4] = inVerts[2];
     outVerts[5] = inVerts[1];
};
void Outputsubdivision(VertexOut v[6],inout Trianglestream<GeoOut> triStream)
{
      GeoOut gout[6];
      [unroll]
      for(int i = 0; i < 6; ++i)
      {
          //将顶点变换到世界空间
          gout[i].PosW = mul(float4(v[i].PosL, 1.Of), gWorld).xyz;   
          gout[i].NormalW = mul(v[i].NormalL,(float3x3)gWorldlnvTranspose);
          
          //把顶点变换到齐次裁剪空间
          gout[i].PosH = mul(float4(v[i].PosL, 1.Of), gWorldViewProj);  
          gout[i].Tex = v[i].Tex;
      }
          //         1
          //         *
          //        / \
          //       /   \
          //   m0*-------*m1
          //    / \    / \
         //    /   \  /   \
         //   *-----*------*
         //   0     m2      2

    //我们可以将细分的小三角形绘制到两个三角形带中去:
    //	三角形带1:底端的3个三角形
    //	三角形带2:顶部的三角形
    [unroll]
    for(int j = 0; j < 5; ++j)
    {
       triStream.Append(gout[j]);
    }
    triStream.Restartstrip();
    
    triStream.Append(gout[1]);
    triStream.Append(gout[5]);
    triStream.Append(gout[3]);
}

[maxvertexcount(8)]
void GS(triangle VertexOut gin[3], inout TriangleStream<GeoOut>)
(
       VertexOut v[6];
       Subdivide(gin, v);
       Outputsubdivision(v, triStream);
}

若给出一个输入图元,几何着色器也可以根据某些条件而选择不输出任何数据。通过这 种方式,几何着色便可以轻易地“销毁”几何图形。

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

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

相关文章

MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3:EXPLAIN ANALYZE

文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3&#xff1a;EXPLAIN ANALYZEEXPLAIN ANALYZE介绍EXPLAIN ANALYZE的特性EXPLAIN 和EXPLAIN ANALYZE的结果对比例题例题解析参考 MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3&#xff1a;EXPLAIN ANALYZE EXPLAIN…

部门来了个测试人,听说是00后,上来一顿操作给我看呆了...

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

网络原理(TCP/UDP)

目录 一. 网络基础 1. IP地址 2. 端口号 3. 协议 4. OSI七层模型 二. UDP协议 2.1 UDP的协议端格式&#xff1a; 2.2 UDP的特点 三. TCP协议 3.1 TCP协议段格式 3.2 TCP原理 &#xff08;1&#xff09;确认应答机制 &#xff08;2&#xff09;超时重传机制 &#xff…

CmBacktrace库在工程中的添加和应用

CmBacktrace 介绍在工程中添加CmBacktrace断言打印全局变量的值循环输出错误信息串口处理看门狗处理 介绍 CmBacktrace下载 CmBacktrace &#xff08;Cortex Microcontroller Backtrace&#xff09;是一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位&#xff0c;错…

Javaee Spring template实现查询数据库表内容 基于半xml半注解

昨天用基于xml配置实现template查询数据库&#xff0c;今天基于半xml半注解方式实现,使用注解需要导入spring-aop-5.3.8.jar 导入jar包 项目结构&#xff1a; 其他代码在&#xff0c;先前上一篇文章已经给出 AccountServiceImpl package wwx.dao;import org.springframework…

定时器中断实验

实现内容 利用TIM3的定时器中断来控制DS1的翻转&#xff0c;在主函数用DS0 的翻转来提示程序正在运行。 定时器介绍 定时器可以认为是一个计数器&#xff1b;给定计数器一个初值&#xff0c;每当计数一次&#xff0c;就会走过一个固定的时间&#xff0c;当达到我们给定的初值…

强大的图像处理:ImageKit10.E ActiveX Crack

强大的图像处理&#xff01; ImageKit10 ActiveX 是一个组件&#xff0c;允许您快速轻松地向应用程序添加图像处理功能。使用 ImageKit10 ActiveX&#xff0c;您可以编写从 TWAIN 扫描仪和数码相机检索图像的应用程序;加载和保存图像文件并将图像从一种格式转换为另一种格式;编…

数字电路和模拟电路-半导体三极管

目录 1 什么是三极管&#xff1f; 1.1 放大状态时的偏执条件 1.1.1发射结加正向电压&#xff0c;扩散运动形成发射极电流IE 1.1.2扩散到基区的自由电子与空穴的复合运动形成基极电流IB 1.1.3集电结加反向电压&#xff0c;漂移运动形成集电极电流Ⅰc 2 三极管工作原理 2.…

5.图论(0x3f:从周赛中学算法 2022下)

来自0x3f【从周赛中学算法 - 2022 年周赛题目总结&#xff08;下篇&#xff09;】&#xff1a;https://leetcode.cn/circle/discuss/WR1MJP/ 周赛中的图论题目比较少&#xff0c;除了下面选的 DFS、BFS、拓扑排序、基环树、二分图判定等&#xff0c;还有最短路、DFS 时间戳等&a…

CloudCompare二次开发之如何设计界面ui与功能实现?

文章目录 0.引言1.创建界面ui相关文件2.添加界面ui相关文件到CloudCompare工程3.修改工程相关文件4.结果展示 0.引言 CloudCompare源代码编译成功后&#xff0c;即可进行二次开发&#xff0c;可以通过修改源码实现二次开发&#xff0c;二次开发基础功能见&#xff08;CloudComp…

什么是文件共享软件?文件传输软件如何共享?

它是一个文件共享软件应用程序&#xff0c;可让强大的数据保护层下将任何大小的文件发送到世界上的任何地方。以光速发送和共享无限数量的文件。可以提交门户并使用语言&#xff0c;品牌&#xff0c;存储等自定义门户。可以选择一个存储点&#xff0c;例如文件传输软件&#xf…

[入门必看]数据结构4.2:串的模式匹配

[入门必看]数据结构4.2&#xff1a;串的模式匹配 第四章 串4.2 串的模式匹配知识总览4.2.1_朴素模式匹配算法4.2.2_1_KMP算法4.2.2_2_求next数组4.2.3_KMP算法的进一步优化 4.2.1_朴素模式匹配算法什么是字符串的模式匹配朴素模式匹配算法通过数组下标实现朴素模式匹配算法代码…

http(1)

主要介绍http 1.0 我们在浏览器中输入一个网址&#xff0c;稍等片刻就看见了网页 客户端会发送一个http请求&#xff0c;要求返回cn.bing.com这个网址&#xff0c;服务器收到请求后就会返回一个html页面 &#xff08;服务器根据请求找到客户端想要的资源&#xff0c;然后把这个…

[LeetCode]路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 是指没有子节点…

【并发编程】线程池的原理和源码分析

线程使用上可能的问题 我们一般通过new Thread().start();来创建和运行一个线程&#xff0c;如果在业务过程中有大量场景需要使用多线程来并发&#xff0c;那么就会有以下问题 需要频繁的创建和销毁线程 &#xff0c;需要消耗CPU资源如果创建和销毁的线程的数量过多(大于CPU核…

CMOS图像传感器——从传感器冗余说起

在这先抛出一个概念,什么是成像圈?众所周知,相机的镜头近似于圆柱体,光线透过圆筒子投射出的大都是圆形。我们可以拿一个镜头演示一下,当这个圆圈投在传感器所在焦平面时,我们称之为像场。像场的边界我们称之为成像圈,成像圈是圆的,但是传感器是矩形,天圆地方的怎么放…

Lombok插件下载与离线安装

Lombok插件下载与离线安装 首先你既然搜要离线安装或下载&#xff0c;那么肯定也是在IDEA工具里面&#xff0c;无法搜索到&#xff0c;或者自动下载安装失败吧&#xff1f; 安装包下载地址 记得和 idea版本一样&#xff0c; 如果不知道啥版本看下面

CleanMyMac X4.15重大更新 新功能菜单发布

CleanMyMac&#xff0c;一款电脑清理软件&#xff0c;可以帮助你清理垃圾文件、优化系统性能、管理应用程序等。它就像你的电脑管家&#xff0c;让你的电脑始终保持最佳状态。无论是手机还是电脑&#xff0c;在使用一段时间之后都可能会发生卡顿的现象&#xff0c;很多小伙伴会…

C++ 高级数据结构————[ 单调栈 ]

每周一篇的算法文章来了 今天讲解的是高级数据结构中的——单调栈 单调栈&#xff0c;顾名思义&#xff0c;就是升级版的栈&#xff08;&#xff09; 先回顾一下栈把 栈&#xff0c;是一种线性表&#xff0c;它的特点是只能从一边进出&#xff0c;并且先进后出&#xff0c;后进…

Windows入门篇一之MSDN手册的使用和第一个窗口程序

Windows入门篇之MSDN手册的使用和第一个窗口程序 MSDN手册MSDN手册是什么MSDN手册的下载和安装MSDN手册的使用 第一个窗口程序项目的创建第一个简单的窗口程序 MSDN手册 MSDN手册是什么 MSDN手册是VS中的一个帮助手册&#xff0c;帮助初学者学习Windows编程&#xff0c;来查找…