GLSL教程 第8章:几何着色器

目录

8.1 几何着色器的介绍

几何着色器的主要功能:

几何着色器的工作流程:

8.2 实现基本的几何变换

示例:将三角形扩展成多个三角形

8.3 几何着色器的高级应用

1. 粒子系统

2. 光晕效果

3. 线框模型

小结


       几何着色器是图形管线中的一种高级着色器类型,用于处理和生成图形原语(如点、线和三角形)的几何数据。与顶点着色器和片段着色器不同,几何着色器可以生成新的几何体,并对现有几何体进行更复杂的操作和处理。本章将介绍几何着色器的基本概念、实现方法和高级应用。

8.1 几何着色器的介绍

        几何着色器位于图形管线的顶点着色器和片段着色器之间。它接收来自顶点着色器的数据,处理这些数据并生成新的几何体,最终将这些几何体传递给片段着色器进行渲染。

几何着色器的主要功能
  • 生成新的几何体:根据输入的几何体生成新的几何体,例如,将一个三角形扩展成多个三角形或生成粒子效果。
  • 修改现有几何体:对输入的几何体进行变形、细分或其他操作。
  • 输出多个几何体:将一个输入几何体转化为多个输出几何体,从而在渲染过程中创建复杂的效果。
几何着色器的工作流程
  1. 输入几何体:几何着色器接收来自顶点着色器的几何体数据。
  2. 处理数据:对输入数据进行处理,如变形、细分、扩展等。
  3. 输出几何体:生成新的几何体,并将其传递到片段着色器进行渲染。
            +----------------+   +------------------+
顶点数据 ---> | 顶点着色器      |-->| 几何着色器        |---> 渲染+----------------+   +------------------+

几何着色器在图形管线中的位置 

解释:

  • 顶点着色器:处理顶点数据,将其传递到几何着色器。
  • 几何着色器:处理并生成新的几何体,将其传递到片段着色器。
  • 片段着色器:处理片段数据,生成最终的图像。
8.2 实现基本的几何变换

        在几何着色器中,我们可以实现基本的几何变换,例如将三角形的每个边扩展成新的三角形。这种技术可以用于实现诸如环境光衰减效果、粒子效果或其他几何效果。

示例:将三角形扩展成多个三角形

顶点着色器代码

#version 330 corelayout(location = 0) in vec3 aPos; // 顶点位置
layout(location = 1) in vec3 aNormal; // 顶点法线out vec3 FragPos; // 传递到片段着色器的片段位置
out vec3 Normal; // 传递到片段着色器的法线uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));Normal = mat3(transpose(inverse(model))) * aNormal;gl_Position = projection * view * vec4(FragPos, 1.0);
}

几何着色器代码

#version 330 corelayout(triangles) in; // 输入几何体类型为三角形
layout(triangle_strip, max_vertices = 6) out; // 输出几何体类型为三角形带,最多输出6个顶点in vec3 FragPos[]; // 从顶点着色器接收的片段位置
in vec3 Normal[]; // 从顶点着色器接收的法线out vec3 TexCoord; // 传递到片段着色器的纹理坐标uniform float offset; // 三角形扩展偏移量void main() {for (int i = 0; i < 3; ++i) {vec3 p0 = FragPos[i];vec3 p1 = FragPos[(i + 1) % 3];vec3 normal = normalize(cross(p1 - p0, FragPos[(i + 2) % 3] - p0));// 计算扩展点vec3 expandedPoint0 = p0 + normal * offset;vec3 expandedPoint1 = p1 + normal * offset;vec3 expandedPoint2 = FragPos[(i + 2) % 3] + normal * offset;// 输出新三角形的三个顶点gl_Position = gl_in[i].gl_Position;TexCoord = vec3(expandedPoint0);EmitVertex();gl_Position = gl_in[(i + 1) % 3].gl_Position;TexCoord = vec3(expandedPoint1);EmitVertex();gl_Position = gl_in[(i + 2) % 3].gl_Position;TexCoord = vec3(expandedPoint2);EmitVertex();EndPrimitive();}
}

解释:

  • layout(triangles) in:指定输入几何体类型为三角形。
  • layout(triangle_strip, max_vertices = 6) out:指定输出几何体类型为三角形带,最多输出6个顶点。
  • EmitVertex()EndPrimitive():用于发射顶点和结束当前图元。
8.3 几何着色器的高级应用

        几何着色器可以用于实现更复杂的效果,如粒子系统、光晕效果、线框模型等。以下是几个高级应用的示例:

1. 粒子系统

        粒子系统用于创建动态和复杂的效果,如火焰、烟雾和雨滴。几何着色器可以生成大量粒子并对其进行处理和渲染。

顶点着色器代码

#version 330 corelayout(location = 0) in vec3 aPos; // 粒子位置
layout(location = 1) in vec3 aVel; // 粒子速度out vec3 FragPos; // 传递到片段着色器的片段位置uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));gl_Position = projection * view * vec4(FragPos, 1.0);
}

几何着色器代码

#version 330 corelayout(location = 0) in vec3 aPos; // 粒子位置
layout(location = 1) in vec3 aVel; // 粒子速度out vec3 FragPos; // 传递到片段着色器的片段位置uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));gl_Position = projection * view * vec4(FragPos, 1.0);
}

解释:

  • layout(points) in:指定输入几何体类型为点。
  • layout(triangle_strip, max_vertices = 4) out:指定输出几何体类型为三角形带,最多输出4个顶点。
  • EmitVertex()EndPrimitive():用于发射顶点和结束当前图元。
粒子系统效果

 

2. 光晕效果

        光晕效果可以增强物体的发光效果,使其看起来更加真实和生动。几何着色器可以生成多个光环并对其进行处理。

顶点着色器代码

#version 330 corelayout(location = 0) in vec3 aPos; // 顶点位置out vec3 FragPos; // 传递到片段着色器的片段位置uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));gl_Position = projection * view * vec4(FragPos, 1.0);
}

几何着色器代码

#version 330 corelayout(triangles) in; // 输入几何体类型为三角形
layout(triangle_strip, max_vertices = 12) out; // 输出几何体类型为三角形带,最多输出12个顶点in vec3 FragPos[]; // 从顶点着色器接收的片段位置out vec3 TexCoord; // 传递到片段着色器的纹理坐标uniform float glowRadius; // 光晕半径void main() {vec3 center = (FragPos[0] + FragPos[1] + FragPos[2]) / 3.0;vec3 offset = vec3(glowRadius);for (int i = 0; i < 3; ++i) {vec3 expandedPos = FragPos[i] + offset;gl_Position = gl_in[i].gl_Position + vec4(expandedPos - FragPos[i], 0.0);TexCoord = vec3(expandedPos);EmitVertex();expandedPos = FragPos[(i + 1) % 3] + offset;gl_Position = gl_in[(i + 1) % 3].gl_Position + vec4(expandedPos - FragPos[(i + 1) % 3], 0.0);TexCoord = vec3(expandedPos);EmitVertex();EndPrimitive();}
}

解释:

  • layout(triangles) in:指定输入几何体类型为三角形。
  • layout(triangle_strip, max_vertices = 12) out:指定输出几何体类型为三角形带,最多输出12个顶点。
  • EmitVertex()EndPrimitive():用于发射顶点和结束当前图元。
光晕效果

 

3. 线框模型

        线框模型用于显示模型的边缘结构,使模型的结构更加清晰。几何着色器可以生成线框模型的几何数据并进行渲染。

顶点着色器代码

#version 330 corelayout(location = 0) in vec3 aPos; // 顶点位置out vec3 FragPos; // 传递到片段着色器的片段位置uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));gl_Position = projection * view * vec4(FragPos, 1.0);
}

几何着色器代码

#version 330 corelayout(triangles) in; // 输入几何体类型为三角形
layout(line_strip, max_vertices = 6) out; // 输出几何体类型为线带,最多输出6个顶点in vec3 FragPos[]; // 从顶点着色器接收的片段位置out vec3 TexCoord; // 传递到片段着色器的纹理坐标void main() {for (int i = 0; i < 3; ++i) {gl_Position = gl_in[i].gl_Position;TexCoord = FragPos[i];EmitVertex();gl_Position = gl_in[(i + 1) % 3].gl_Position;TexCoord = FragPos[(i + 1) % 3];EmitVertex();EndPrimitive();}
}

解释:

  • layout(triangles) in:指定输入几何体类型为三角形。
  • layout(line_strip, max_vertices = 6) out:指定输出几何体类型为线带,最多输出6个顶点。
  • EmitVertex()EndPrimitive():用于发射顶点和结束当前图元。
小结

        在本章中,我们详细介绍了几何着色器的基本概念、实现方法和高级应用。几何着色器作为图形管线中的重要组成部分,可以处理和生成几何体,从而实现各种复杂的渲染效果。通过学习几何着色器,我们能够在图形渲染中实现更多创意和视觉效果,提高渲染的灵活性和表现力。

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

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

相关文章

应用层自定义协议以及序列化和反序列化

文章目录 应用层自定义协议以及序列化和反序列化1、应用层自定义协议1.1、应用层1.2、协议 2、序列化和反序列化3、TCP 为什么支持全双工4、jsoncpp基础4.1、序列化4.2、反序列化 5、实现网络版计算器6、手写序列化和反序列化 应用层自定义协议以及序列化和反序列化 1、应用层…

爬取贴吧的标题和链接

免责声明 感谢您学习本爬虫学习Demo。在使用本Demo之前&#xff0c;请仔细阅读以下免责声明&#xff1a; 学习和研究目的&#xff1a;本爬虫Demo仅供学习和研究使用。用户不得将其用于任何商业用途或其他未经授权的行为。合法性&#xff1a;用户在使用本Demo时&#xff0c;应确…

智能算法驱动的爬虫平台:解锁网络数据的无限潜力

摘要 在信息爆炸的时代&#xff0c;网络数据如同深海宝藏&#xff0c;等待着有识之士发掘其无尽价值。本文将探索智能算法驱动的爬虫平台如何成为解锁这一宝库的关键&#xff0c;不仅剖析其技术优势&#xff0c;还通过实例展示它如何助力企业与开发者高效、稳定地采集数据&…

C语言 ——— 数组指针的定义 数组指针的使用

目录 前言 数组指针的定义 数组指针的使用 前言 之前有编写过关于 指针数组 的相关知识 C语言 ——— 指针数组 & 指针数组模拟二维整型数组-CSDN博客 指针数组 顾名思义就是 存放指针的数组 那什么是数组指针呢&#xff1f; 数组指针的定义 何为数组指针&#xf…

【QT】UDP

目录 核心API 示例&#xff1a;回显服务器 服务器端编写&#xff1a; 第一步&#xff1a;创建出socket对象 第二步&#xff1a; 连接信号槽 第三步&#xff1a;绑定端口号 第四步&#xff1a;编写信号槽所绑定方法 第五步&#xff1a;编写第四步中处理请求的方法 客户端…

JAVA开发工具IDEA如何连接操作数据库

一、下载驱动 下载地址&#xff1a;【免费】mysql-connector-j-8.2.0.jar资源-CSDN文库 二、导入驱动 鼠标右击下载到IDEA中的jar包&#xff0c;选择Add as Library选项 如图就导入成功 三、加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); 四、驱动管理…

【C++】——红黑树(手撕红黑树,彻底弄懂红黑树)

目录 前言 一 红黑树简介 二 为什么需要红黑树 三 红黑树的特性 四 红黑树的操作 4.1 变色操作 4.2 旋转操作 4.3 插入操作 4.4 红黑树插入代码实现 4.5 红黑树的删除 五 红黑树迭代器实现 总结 前言 我们之前都学过ALV树&#xff0c;AVL树的本质就是一颗平…

计算机实验室排课查询小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#xff0c;取消预约管理&#xff0c;实验课程管理&#xff0c;实验报告管理&#xff0c;报修信息管理&#xff0…

Linux的yum源安装MySQL5.7

linux的yum源安装MySQL5.7 一、MySQL 1、简介 MySQL 是一种流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典公司 MySQL AB 开发&#xff0c;后来被 Oracle Corporation 收购。它是一个开源软件&#xff0c;提供了高效、稳定和可靠的数据管理解决…

Spring AI (三) 提示词对象Prompt

3.提示词对象Prompt 3.1.Prompt Prompt类的作用是创建结构化提示词, 实现了ModelRequest<List<Message>>接口 Prompt(String contents)&#xff1a;创建一个包含指定内容的Prompt对象。 Prompt(String contents, ChatOptions modelOptions)&#xff1a;创建一个…

某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]

文章目录 某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内…

DolphinDB Web 端权限管理:可视化操作指南

在现代数据库管理中&#xff0c;高效和直观的权限管理对于用户的数据安全是至关重要的。过去 DolphinDB 用户需要依赖系统脚本来管理用户和权限&#xff0c;这对于缺乏技术背景的管理员来说既复杂又容易出错。 为了提升用户体验和操作效率&#xff0c;DolphinDB 目前在 Web 上…

数据库设计三范式

文章目录 数据库设计三范式第一范式第二范式第三范式一对一怎么设计主键共享外键唯一 一对多怎么设计多对多怎么设计 数据库设计三范式 数据库表设计的原则。教你怎么设计数据库表有效&#xff0c;并且节省空间。 如果客户有速度要求极致&#xff0c;可以不用。根据客户需求来 …

MySQL数据库练习(5)

1.建库建表 # 使用数据库 use mydb16_trigger;# 表格goods create table goods( gid char(8) primary key, name varchar(10), price decimal(8,2), num int);# 表格orders create table orders( oid int primary key auto_increment, gid char(10) not null, name varchar(10…

scrapy 爬取旅游景点相关数据(一)

第一节 Scrapy 练习爬取穷游旅游景点 配套视频可以前往B站&#xff1a;https://www.bilibili.com/video/BV1Vx4y147wQ/?vd_source4c338cd1b04806ba681778966b6fbd65 本项目为scrapy 练手项目&#xff0c;爬取的是穷游旅游景点列表数据 0 系统的环境 现在网上可以找到很多scr…

Pytorch使用教学6-张量的分割与合并

在使用PyTorch时&#xff0c;对张量的分割与合并是不可避免的操作&#xff0c;本节就带大家深刻理解张量的分割与合并。 在开始之前&#xff0c;我们先对张量的维度进行深入理解&#xff1a; t2 torch.zeros((3, 4)) # tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.…

C语言边界互通传送迷宫

目录 注意事项开头程序程序的流程图程序输入与输出的效果结尾 注意事项 程序里有关字符’\033’的输出都关于Sunshine-Linux的其中一篇博客——《printf函数高级用法设置打印字体颜色和背景色等》 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们来看一下我用C语…

现代Java开发:使用jjwt实现JWT认证

前言 jjwt 库 是一个流行的 Java 库&#xff0c;用于创建和解析 JWT。我在学习spring security 的过程中看到了很多关于jwt的教程&#xff0c;其中最流行的就是使用jjwt实现jwt认证&#xff0c;但是教程之中依然使用的旧版的jjwt库&#xff0c;许多的类与方法已经标记弃用或者…

InsCode GPU服务器快速使用

文章目录 1. 背景介绍2. 环境配置 1. 背景介绍 InsCode服务器地址&#xff1a;https://inscode.csdn.net/workbench?tabcomputed。 2. 环境配置 新建环境后&#xff0c;按照如下步骤快速配置&#xff0c;以便后续执行深度学习模型训练。 数据 openlane 环境依赖 Copy Mini…

数据结构与算法--顺序表(Java)

&#x1f4dd;个人主页&#x1f339;&#xff1a;誓则盟约 ⏩收录专栏⏪&#xff1a;Java SE &#x1f921;往期回顾&#x1f921;&#xff1a;Java SE--基本数据类型&#xff08;详细讲解&#xff09; &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 什么…