曲面细分着色器---细分二维四边形

2023-10-31

openGL系列文章目录

前言

术语Tessellation(镶嵌)是指一大类设计活动,通常是指在平坦的表面上,用各种几何形状的瓷砖相邻排列以形成图案。它的目的可以是艺术性的或实用性的,很多例子可以追溯到几千年前在3D 图形学中,Tessellation 指的是有点不同的东西(曲面细分),但显然是由它的经典对应物(镶嵌)启发而成的。在这里,曲面细分指的是生成并且操控大量三角形以渲染复杂的形状和表面,尤其是使用硬件进行渲染。曲面细分是OpenGL 核心近期才增加的新功能,在2010 年的4.0 版本中出现。

一、曲面细分

OpenGL 对硬件曲面细分的支持,通过3 个管线阶段提供:
(1)曲面细分控制着色器;
(2)曲面细分器;
(3)曲面细分评估着色器。
第(1)和第(3)阶段是可编程的;而中间的第(2)阶段不是。为了使用曲面细分,
程序员通常会提供控制着色器和评估着色器。
曲面细分器(其全名是曲面细分图元生成器,或TPG)是硬件支持的引擎,可以生成固
定的三角形网格。②控制着色器允许我们配置曲面细分器要构建什么样的三角形网格。然后,
评估着色器允许我们以各种方式操控网格。然后,被操控过的三角形网格,会作为通过管
线前进的顶点的源数据。回想一下图2.2,在管线上,曲面细分着色器位于顶点着色器和几
何着色器阶段之间。
让我们从一个简单的应用程序开始,该应用程序只使用曲面细分器创建顶点的三角形网
格,然后在不进行任何操作的情况下显示它。为此,我们需要以下模块。
(1)C++/OpenGL 应用程序:
创建一个摄像机和相关的MVP 矩阵,视图(v)和投影(p)矩阵确定摄像机朝向,模
型(m)矩阵可用于修改网格的位置和方向。
(2)顶点着色器:
在这个例子中基本上什么都不做,顶点将在曲面细分器中生成。
(3)曲面细分控制着色器:
指定曲面细分器要构建的网格。
(4)曲面细分评估着色器:
将MVP 矩阵应用于网格中的顶点。
(5)片段着色器:
只需为每个像素输出固定颜色。
程序12.1 显示了整个应用程序的代码。即使像这样的简单示例也相当复杂,因此许多代
码元素都需要解释。请注意,这是我们第一次使用除顶点和片段着色器之外的组件构建
GLSL 渲染程序。因此,我们实现了createShaderProgram()的4 参数重载版本。

二、细分二维四边形

理解OpenGL的硬件细分操作最好的方法就是细分一个二维四边形,而后可视化细分的结果。使用线性插值后,产生的三角形和细分坐标(u,v)相关。通过使用不同的输入和输出细分级别产生四边形对于学习很有价值。

曲面细分图元生成器(TPG)根据6个参数来划分(u,v)空间。它们是内部细分级别(0和1两个)和外部细分级别(0-3共6个)。下面是对它们的描述:

外部细分级别0(OL0):沿v方向,u坐标为0的边进行划分的个数。
外部细分级别1(OL1):沿u方向,v坐标为0的边进行划分的个数。
外部细分级别2(OL2):沿v方向,u坐标为1的边进行划分的个数。
外部细分级别3(OL3):沿u方向,v坐标为1的边进行划分的个数。
内部细分级别0(IL0):沿u方向进行内部划分的个数。
内部细分级别1(IL1):沿v方向进行内部划分的个数。
下图显示了划分级别对应的空间划分。外部划分级别定义了沿边划分的个数,内部划分级别定义了
在这里插入图片描述

这6个细分级别可以通过数组g_TessLevelOuter和gl_TessLevelInner设置。比如,gl_TessLevelInner[0]对应IL0,gl_TessLevelOuter[2]对应OL2。

我们绘制一个细分四边形来帮助理解OpenGL的四边形细分,如下图所示。
在这里插入图片描述
我们使用线性插值进行细分,图中的三角形代表了四边形的划分。x轴对应u坐标,y轴对应v坐标。三角形的顶点由TPG产生。细分的三角形数量,可以直接从图中看出。比如,何止外部细分级别为2,内部细分级别为8时,我们可以看到外部的边被划分为两部分,在内部,(u,v)被划分为8部分。

在进行代码实现之前,我们先讨论以下线性插值。对于下图的四边形,它内部的任一点可以通过对四边形四角的顶点插值得到。
在这里插入图片描述
我们通过TPG生成u,v坐标,然后通过上图的线性插值确定它在四边形中的位置。

准备

我们通过Uniform变量Inner和Outer在OpenGL程序中设置细分级别。我们使用之前提到的几何着色器来处理这些三角形。

然后,设置OpenGL程序渲染包含4个顶点的Patch图元。

实现

我们采取下面的步骤来进行四边形细分:

  1. 使用下面的代码作为顶点着色器:

  2. #version 400 layout (location = 0 ) in vec2 VertexPosition; void main() { gl_Position = vec4(VertexPosition, 0.0, 1.0); }

  3. 使用下面的代码作为曲面细分控制着色器:

  4. #version 400 layout( vertices=4 ) out; uniform int Outer; uniform int Inner; void main() { // Pass along the vertex position unmodified gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; gl_TessLevelOuter[0] = float(Outer); gl_TessLevelOuter[1] = float(Outer); gl_TessLevelOuter[2] = float(Outer); gl_TessLevelOuter[3] = float(Outer); gl_TessLevelInner[0] = float(Inner); gl_TessLevelInner[1] = float(Inner); }

  5. 使用下面代码作为曲面细分计算着色器:

  6. #version 400 layout( quads, equal_spacing, ccw ) in; uniform mat4 MVP; void main() { float u = gl_TessCoord.x; float v = gl_TessCoord.y; vec4 p0 = gl_in[0].gl_Position; vec4 p1 = gl_in[1].gl_Position; vec4 p2 = gl_in[2].gl_Position; vec4 p3 = gl_in[3].gl_Position; // Linear interpolation gl_Position = p0 * (1-u) * (1-v) + p1 * u * (1-v) + p3 * v * (1-u) + p2 * u * v; // Transform to clip coordinates gl_Position = MVP * gl_Position; }

  7. 使用专栏文章在着色后的网格上绘制线框中的几何着色器。

  8. 使用下面的代码作为片段着色器:

#version 400
uniform float LineWidth;
uniform vec4 LineColor;
uniform vec4 QuadColor;
noperspective in vec3 EdgeDistance;
// From geometry shader
layout ( location = 0 ) out vec4 FragColor;
float edgeMix()
{
//insert code here to determine how much of the edge
//color to include (see recipe “Drawing a wireframe on
//top of a shaded mesh”). **
}
void main()
{
float mixVal = edgeMix();
FragColor=mix( QuadColor, LineColor, mixVal);
}
6. 在OpenGL程序中设置Patch图元顶点个数:

glPatchParameteri(GL_PATCH_VERTICES, 4);
7. 渲染Patch图元。

原理

我们的顶点着色器在这里只用来传递参数。

我们在TCS中定义Patch图元图元的顶点数目:

layout (vertices=4) out
在main函数,我们没有对顶点进行修改,只是进行了细分级别的设置。所有4个外部细分级别被设置为变量Outer的值,所有内部细分级别被设置为变量Inner的值。

在曲面细分计算着色器,我们设置了一些其它的细分参数:

layout ( quads, equal_spacing, ccw ) in;
参数quads表示TPG进行的是四边形细分。参数equal_spacing表示所有细分大小相同,最后一个参数ccw表示产生的顶点的顺序是逆时针的。

在TES的main函数,我们通过数组gl_TessCoord获取参数坐标。然后读取数组gl_in中存储的Patch图元的4个顶点信息。最后将这些信息存储在临时变量中进行插值计算。

插值计算的结果赋值给变量gl_Position。最后,使用模型视图投影矩阵转换顶点坐标到剪切空间。

在片段着色器,我们通过混合函数来渲染三角形的边和非边部分。

参阅

专栏文章在着色后的网格上绘制线框

参考

OpenGL_4.0_Shading_Language_Cookbook

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

曲面细分着色器---细分二维四边形 的相关文章

  • 如何在不使用 Kinect SDK 函数的情况下将深度空间中的点转换为 Kinect 中的颜色空间?

    我正在做一个增强现实应用程序 将 3D 对象叠加在用户的彩色视频之上 使用 Kinect 1 7 版本 虚拟对象的渲染在 OpenGL 中完成 我已经成功地在深度视频上叠加了 3D 对象 只需使用 NuiSensor h 标头中深度相机的固
  • 如何在 GLSL 1.3 和 OpenGL 2.1 中使用位运算

    我正在尝试编写一个使用许多位操作的着色器 事实上 从 glsl 1 30 开始就支持它们 但我只使用 OpenGL 2 1 有没有办法在我的 OpenGL 版本中使用位运算 所有 SM3 兼容 OpenGL 2 1 硬件支持limited整
  • 在 OpenGL 中使用不同的着色器程序?

    我必须在 OpenGL 中针对不同的对象使用两个不同的着色器程序 我发现我必须使用glUseProgram 在不同的着色器程序之间切换 但对此没有太多信息 鉴于我有两个用于不同对象的不同着色器程序 如何为每个着色器程序生成和绑定 VAO 和
  • 在 3D 场景中实现“抓取”相机平移工具

    在我的场景中 我有想要 抓取 的地形 然后在移动光标时让相机平移 其高度 视图向量 视野等全部保持不变 因此 最初的 抓取 点将是世界空间中的工作点 我希望在拖动时该点保留在光标下方 我当前的解决方案是获取前一个和当前的屏幕点 取消投影它们
  • 移动/调整大小期间 opengl 窗口冻结

    我正在使用 LWJGL 开发游戏 移动窗口时 计划将来添加调整大小代码 渲染循环冻结 我希望它在移动时继续以某种方式运行 LWJGL 不包括 glutMainLoop Display属于OpenGL 而不是Java 相关代码 regular
  • 渲染 TTF SDL2.0 opengl 3.1

    我正在使用 SDL2 0 并使用 半现代 opengl 3 1 我希望向我的应用程序添加文本叠加 并在应用程序中呈现 TTF 我将如何使用现代 OpenGL 来解决这个问题 编辑 根据 genpfault 的建议 我尝试使用 SDL TTF
  • Opengl 视频纹理

    我正在使用 Visual Studio 10 在 Windows 上用 C 开发 opengl 应用程序 目前我在立方体上使用静态纹理 但我想集成视频纹理 你知道我可以使用哪个库来打开和解密视频吗 查看 ffmpeg libavformat
  • 如何计算正切和副法线?

    谈谈OpenGL着色语言 GLSL 中的凹凸贴图 镜面高光之类的东西 I have 顶点数组 例如 0 2 0 5 0 1 0 2 0 4 0 5 法线数组 例如 0 0 0 0 1 0 0 0 1 0 0 0 世界空间中点光源的位置 例如
  • glDeleteTextures在Windows上似乎没有释放纹理内存,有没有解决办法?

    我的 openGL 应用程序内存不足 遇到一些问题 我正在尝试找出我的问题 为此 我创建了一个小型测试程序 它基本上只是从调用 glDeleteTextures 的文件中加载一个巨大的纹理 然后再次加载它 如果我在 OSX 上运行这个测试程
  • 为什么我的 CAOpenGLLayer 更新速度比之前的 NSOpenGLView 慢?

    我有一个在 Mac OS X 上渲染 OpenGL 内容的应用程序 最初它渲染到 NSOpenGLView 然后我将其更改为渲染到 CAOpenGLLayer 子类 当我这样做时 我看到了巨大的性能损失 帧速率减半 鼠标响应能力降低 卡顿
  • OpenGL什么时候完成函数中指针的处理?

    OpenGL有多项功能 http www opengl org wiki GLAPI glTexSubImage2D直接获取指针 他们中有一些从这些指针读取数据 http www opengl org wiki GLAPI glBuffer
  • 创建并使用我自己的纹理图集的 mipmap

    我目前正在使用自动 mipmap 生成 C OpenTK GL GenerateMipmap GenerateMipmapTarget Texture2D 我使用的纹理平铺为 16px 的块 所以我的问题是 是否可以使用不会缩小至 1x1
  • 具有交错缓冲区的 openGL glDrawElements

    到目前为止 我只使用了 glDrawArrays 并希望转向使用索引缓冲区和索引三角形 我正在绘制一个有点复杂的对象 其中包含纹理坐标 法线和顶点坐标 所有这些数据都收集到一个交错的顶点缓冲区中 并使用类似于以下的调用进行绘制 假设所有血清
  • 使用 gl_FragColor 与 vec4 颜色?

    似乎有很多不明确的地方gl FragColor被弃用 例如 它缺失在GLSL 4 40 规范 https www khronos org registry OpenGL specs gl GLSLangSpec 4 40 pdf 但它包含在
  • 使用顶点缓冲区对象 (VBO) 渲染 Kinect 点云

    我正在尝试制作一个动态点云可视化工具 使用 Kinect 传感器每帧更新这些点 为了抓取帧 我使用 OpenCV 和 GLUT 来显示 OpenCV API 对于点 xyz 位置返回 640 x 480 float 对于 rgb 颜色数据返
  • nVidia 和 ATI 之间的 OpenGL 渲染差异

    最近 我将 ATI 驱动程序 我使用的是 HD7970 更新为最新版本 但我的 OpenGL 项目的一些对象停止工作 更重要的是 他们适用于 nVidia 最新驱动程序 在 960m 上测试 ATI 和 nVidia 渲染管道之间有什么我应
  • 新显卡上的 nvoglv32.dll 中的绘制调用崩溃

    几天前 由于一些硬件更改 我设置了计算机并安装了新的 Windows 8 副本 其中 我将显卡从 Radeon HD 7870 更改为 Nvidia GTX 660 再次设置 Visual Studio 11 后 我从 Github 下载了
  • 3D 图形批处理

    很多网站 文章都说 批量 批 批 有人可以解释一下着色器中的 批处理 代表什么吗 即 是否 改变纹理 更改任意着色器变量 意味着某些东西不能 批处理 最简单的总结方法就是尝试尽可能少地调用 API 来绘制您需要绘制的内容 使用顶点数组或 V
  • sRGB 纹理。它是否正确?

    我最近阅读了一些有关 sRGB 格式以及它们如何允许硬件自动对典型显示器执行色彩校正的文章 作为我阅读的一部分 我发现您可以使用普通纹理和返回结果上的 pow 函数来模拟此步骤 无论如何 我想问两个问题 因为我以前从未使用过此功能 首先 有
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半

随机推荐

  • 什么是MMU,MMU的作用

    I 什么是MMU MMU的作用 MMU是Memory Management Unit的缩写 针对各种CPU MMU是个可选的配件 MMU负责的是虚拟地址与物理地址的转换 提供硬件机制的内存访问授权 现在的多用户多进程操作系统 需要MMU 才
  • element ui菜单导航栏的动态创建

  • mysql的dba是什么意思_【数据库】mysql dba是什么意思?

    MySQL DBA意思是MySQL数据库管理员 DBA就是数据库管理员的意思 要成为MySQL DBA 不是会哪些东西的问题 而是一定要对MySQL数据库方方面面都得非常精通才行 DBA的职责是 安装和升级数据库服务器 以及应用程序工具 数
  • 前端关于单点登录SSO的知识

    转自前端关于单点登录的知识 什么是单点登录 单点登录 Single Sign On 简称为 SSO 是目前比较流行的企业业务整合的解决方案之一 SSO的定义是在多个应用系统中 用户只需要登录一次就可以访问所有相互信任的应用系统 SSO一般都
  • 前端 HTML空格的六种方式

    HTML提供了5种空格实体 space entity 它们拥有不同的宽度 非断行空格 是常规空格的宽度 可运行于所有主流浏览器 其他几种空格 在不同浏览器中宽度各异 它叫不换行空格 全称No Break Space 它是最常见和我们使用最多
  • Android项目混淆ProGuard详解

    关于混淆 可以借助工具proguardgui bat来了解或者写混淆文件 proguardgui bat是谷歌提供的可视化混淆文件编写工具 proguardgui bat位于android sdk 的tools proguard bin目录
  • python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)

    导读 这篇文章主要介绍如何利用opencv来对图像添加各类噪声 原图 1 高斯噪声 高斯噪声就是给图片添加一个服从高斯分布的噪声 可以通过调节高斯分布标准差 sigma 的大小来控制添加噪声程度 sigma越大添加的噪声越多图片损坏的越厉害
  • 新华三数字化转型与实践 附下载地址

    随着数字技术 智能技术的持续发展 市场环境的不断变化 百行百业相继进入了数字化转型的深水区 这是时代发展的必然 更是建设繁荣数字经济的基础 因此 如何进行数字化转型便成为百行百业需要共同面对的问题 作为数字化解决方案领导者 新华三自身的数字
  • 【高频java面试题】JVM的底层结构

    1 问 说说JVM的底层结构 从左图可知 JVM主要包括四个部分 1 类加载器 ClassLoader 在JVM启动时或者在类运行时将需要的class加载到JVM中 右图表示了从java源文件到JVM的整个过程 可配合理解 关于类的加载机制
  • Python基础语法【5】—— 结构数据类型之元组

    文章目录 一 创建元组 1 使用 直接创建元组 2 使用tuple 函数创建元组 二 访问元组元素 1 使用索引方式访问 2 使用切片方式访问 三 修改元组元素 1 对元组重新进行赋值 2 使用 拼接元组 元组概念 元组和列表类似 也是由一
  • 历年计算机科学领域中各大顶会的获奖文章 ICCV、AAAI、CVPR...

    Original address https jeffhuang com best paper awards html By Conference AAAI ACL CHI CIKM CVPR FOCS FSE ICCV ICML ICSE
  • git submodule的使用

    转自 http webfrogs me 2013 03 20 git submodule 开发过程中 经常会有一些通用的部分希望抽取出来做成一个公共库来提供给别的工程来使用 而公共代码库的版本管理是个麻烦的事情 今天无意中发现了git的gi
  • 【sql基础】条件查询

    写在前面 作者简介 鲸海鹿林 博客主页 鲸海鹿林的主页 名言警句 keep calm and carry on SQL6 查找条件 是 例如 查找学生表中来自北京 city 的学生id和name select id name from st
  • Go + Redis 实现分布式锁

    文章目录 一 前言 1 1 需要对交易订单加锁原因 1 2 加锁方案 二 Go Redis 实现分布式锁 2 1 为什么需要分布式锁 2 2 分布式锁需要具备特性 2 3 实现 Redis 锁应先掌握哪些知识点 2 4 golang 连接r
  • Linux安装MySQL(超详细,附图安装)

    一 安装MySQL服务 1 查看是否已经安装了MySQL rpm qa grep mysql 如果什么都没有 就是还没有装过MySQL 2 下载MySQL安装包 wget i c http dev mysql com get mysql57
  • 项目实战(一)HTML5+CSS3+JS完成前端网站的制作

    css样式 padding 0 margin 0 box sizing border box html body font family segoe UI Tahoma Geneva verdana sans serif line heig
  • c++求数组中最大值最小值

    用algorithm中的 max element min element 这两个函数返回的是位置指针 max element可以获得最大值 1 普通数组用法 include
  • GM(灰度预测模型)

    根据某市1 6月的交通事故数量 建立灰色模型预测GM 1 1 G表示grey M表示model 预测7 8月份的交通事故数量 要求做精度检验 灰色预测的概念 1 灰色系统 白色系统和黑色系统 白色系统是指一个系统的内部特征是完全已知的 既系
  • C++ 继承

    继承允许依据一个类来定义另一个类 为说明继承 首先需要一个基类 当创建一个类时 不需要重新编写新的数据成员和成员函数 只需指定新建的类继承一个已有的类的成员即可 这个已有的类称为基类 新建的类称为派生类 基类 派生类 一个类可以派生自多个类
  • 曲面细分着色器---细分二维四边形

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 曲面细分 二 细分二维四边形 参考 前言 术语Tessellation 镶嵌 是指一大类设计活动 通常是指在平坦的表面上 用各种几何形状的瓷砖相邻排列以形成图案 它的目