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

news2024/9/22 9:35:12

目录

8.1 几何着色器的介绍

几何着色器的主要功能:

几何着色器的工作流程:

8.2 实现基本的几何变换

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

8.3 几何着色器的高级应用

1. 粒子系统

2. 光晕效果

3. 线框模型

小结


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

8.1 几何着色器的介绍

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

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

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

解释:

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

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

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

顶点着色器代码

#version 330 core

layout(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 core

layout(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 core

layout(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 core

layout(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 core

layout(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 core

layout(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 core

layout(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 core

layout(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.coloradmin.cn/o/1950893.html

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

相关文章

Linux——管理本地用户和组(详细介绍了Linux中用户和组的概念及用法)

目录 一、用户和组概念 &#xff08;一&#xff09;、用户的概念 &#xff08;二&#xff09;、组的概念 补充组 主要组 二、获取超级用户访问权限 &#xff08;一&#xff09;、su 命令和su -命令 &#xff08; 二&#xff09;、sudo命令 三、管理本地用户账户 &…

Java面试八股之什么是声明式事务管理,spring怎么实现声明式事务管理?

什么是声明式事务管理&#xff0c;spring怎么实现声明式事务管理&#xff1f; 声明式事务管理是一种编程范式&#xff0c;它允许开发人员通过声明性的配置或注解&#xff0c;而不是硬编码事务处理逻辑&#xff0c;来指定哪些方法或类应该在其上下文中执行事务。这种方法将事务…

Kadane 算法 | 53. 最大子数组和 + 918. 环形子数组的最大和

目录 1 维基百科2 53. 最大子数组和2.1 代码思路2.2 完整代码 3 918. 环形子数组的最大和3.1 代码思路3.2 完整代码 1 维基百科 最大子数组问题 在计算机科学中&#xff0c;最大子数组问题的目标是在数组的一维方向找到一个连续的子数组&#xff0c;使该子数组的和最…

Axious的请求与响应

Axious的请求与响应 1.什么是Axious Axious是一个开源的可以用在浏览器和Node.js的异步通信框架&#xff0c;它的主要作用就是实现AJAX异步通信&#xff0c;其功能特点如下&#xff1a; 从浏览器中创建XMLHttpRequests ~从node.js创建Http请求 支持PromiseAPI 拦截请求和…

[UVM源代码研究] 聊聊UVM中的callback机制

1. callback机制是什么&#xff1f; 以最高效的方式完成芯片验证&#xff0c;一直以来都是验证人员的首要目标&#xff0c;那么最直接的方式就是环境的移植和重用&#xff0c;一个优秀的验证工程师&#xff0c;在开发环境的过程中&#xff0c;一定会考虑环境的继承和重用。 继…

c++ 智能指针shared_ptr与make_shared

shared_ptr是C11引入的一种智能指针&#xff0c;‌它允许多个shared_ptr实例共享同一个对象&#xff0c;‌通过引用计数来管理对象的生命周期。‌当最后一个持有对象的shared_ptr被销毁时&#xff0c;‌它会自动删除所指向的对象。‌这种智能指针主要用于解决资源管理问题&…

简单小案例分析

一、容器和实例关系 <div class"app"><h1>Hello,{{name}}</h1> </div> <div class"app"><h1>Hello,{{name}}</h1> </div><script>//创建Vue实例new Vue({el:".app", //el用于指定当前V…

北大延毕硕士×INFJ | 我解脱了

前言 拿了双证&#xff0c;我终于能静下心来复盘一下我延毕一年的经历了。 给后面也许有相同困境的朋友们做个参考或者心理疏导作用。 延毕的原因 我延毕的主要原因是论文研三的时候论文没有完成&#xff0c;我们专业的论文一般是6个月全身心投入可以完成。我这个人是典型的…

7月24日JavaSE学习笔记

序列化版本控制 序列化&#xff1a;将内存对象转换成序列&#xff08;流&#xff09;的过程 反序列化&#xff1a;将对象序列读入程序&#xff0c;转换成对象的方式&#xff1b;反序列化的对象是一个新的对象。 serialVersionUID 是一个类的序列化版本号 private static fin…

77.WEB渗透测试-信息收集-框架组件识别利用(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;76.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;16&#xff09; java&#xff…

The Llama 3 Herd of Models.Llama 3 模型论文全文

现代人工智能(AI)系统是由基础模型驱动的。本文提出了一套新的基础模型,称为Llama 3。它是一组语言模型,支持多语言、编码、推理和工具使用。我们最大的模型是一个密集的Transformer,具有405B个参数和多达128K个tokens的上下文窗口。本文对Llama 3进行了广泛的实证评价。我们…

【Django】前端技术HTML常用标签(开发环境vscode)

文章目录 安装两个常用插件HTML常用标签定义文档类型DOCTYPE网页的结构html/head//title/body/div标题h1/h2/h3/h4/h5分割线hr段落 p列表ul/li&#xff0c;ol/li超链接a文本span图片img按钮button表格table&#xff08;table、tr、th、td&#xff09;表单form 安装两个常用插件…

深度学习环境配置——总结下近期遇到的”坑“

文章目录 1. 问题1&#xff1a;硬件选择的误区2. 问题2&#xff1a;操作系统的适配难题3. 问题3&#xff1a;深度学习框架的安装陷阱4. 问题4&#xff1a;CUDA与cuDNN的版本匹配问题5. 问题5&#xff1a;网络配置的瓶颈6. 问题6&#xff1a;数据预处理的技巧7. 问题7&#xff1…

CVPR`24 | 4D编辑哪家强?浙大首次提出通用指导4D编辑框架:Instruct 4D-to-4D

文章链接&#xff1a;https://arxiv.org/pdf/2406.09402 项目地址&#xff1a;https://immortalco.github.io/Instruct-4D-to-4D/ 今天和大家一起学习的是Instruct 4D-to-4D&#xff0c;可以通过2D扩散模型实现4D感知和时空一致性&#xff0c;以生成高质量的指令引导的动态场景…

用户使用算力共享平台流程

目录 用户使用算力共享平台流程 一、用户注册与认证 二、接入算力资源 三、任务发布与管理 四、商业调度与资源分配 五、任务执行与结果验证 六、支付与结算 七、评价与信誉建立 算力架构概述 “以案赋能” | 首届“华彩杯”算力应用创新大赛全国总决赛获奖案例选编

【JUC】Java锁介绍

文章目录 阿里锁开发规范乐观锁和悲观锁悲观锁乐观锁 synchronized 类锁、对象锁synchronized有三种应用方式锁相关的8种案例演示&#xff08;对象锁、类锁&#xff09;标准访问ab两个线程&#xff0c;请问先打印邮件还是短信&#xff1f;sendEmail钟加入暂停3秒钟&#xff0c;…

【Python机器学习】决策树的构造——递归构建决策树

我们可以采用递归的原则处理数据集&#xff0c;递归结束的条件是&#xff1a;程序遍历完所有划分数据集的属性&#xff0c;或者每个分支下的所有实例都具有相同的分类。如果所有实例具有相同的分类&#xff0c;则得到一个叶子节点或者终止块。任何到达叶子节点的数据必然属于叶…

软考:软件设计师 — 7.软件工程

七. 软件工程 1. 软件工程概述 &#xff08;1&#xff09;软件生存周期 &#xff08;2&#xff09;软件过程 软件开发中所遵循的路线图称为 "软件过程"。 针对管理软件开发的整个过程&#xff0c;提出了两个模型&#xff1a;能力成熟度模型&#xff08;CMM&#…

uniapp引入自定义图标

目录 一、选择图标&#xff0c;加入购物车 二、下载到本地 三、导入项目 四、修改字体引用路径 五、开始使用 这里以扩展iconfont图标为例 官网&#xff1a;iconfont-阿里巴巴矢量图标库 一、选择图标&#xff0c;加入购物车 二、下载到本地 直接点击下载素材&#xff0…

mysql中You can’t specify target table for update in FROM clause错误

mysql中You can’t specify target table for update in FROM clause错误 You cannot update a table and select directly from the same table in a subquery. mysql官网中有这句话&#xff0c;我们不能在一个语句中先在子查询中从某张表查出一些值&#xff0c;再update这张表…