IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 曲面细分着色器---细分二维四边形 -> 正文阅读

[游戏开发]曲面细分着色器---细分二维四边形

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

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:52:21  更:2022-05-05 11:54:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:50:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码