全球图形学领域教育的领先者、自研引擎的倡导者、底层技术研究领域的技术公开者,东汉书院在致力于使得更多人群具备内核级竞争力的道路上,将带给小伙伴们更多的公开技术教学和视频,感谢一路以来有你的支持。我们正在用实际行动来帮助小伙伴们构建一套成体系的图形学知识架构,你在我们这里获得的不止于那些毫无意义的代码,我们这里更多的是代码背后的故事,以及精准、透彻的理解。我们不会扔给人们一本书或者给个思路让人们去自学,我们是亲自来设计出好的课程,让人们明白到底背后还有哪些细节。

这里插播一个引擎大赛的消息,感兴趣的同学可以看一眼,这也是东汉书院的立项使命:

东汉书院:自研引擎大赛​zhuanlan.zhihu.com

In the displacement mapping example, all we did was use a (very large) texture to drive displacement from a flat surface and then use tessellation to increase the number of polygons in the scene. This is a type of brute-force, data-driven approach to geometric complexity. In the cubicbezier example described here, we will use math to drive geometry—we’re going to render a cubic Bézier patch. If you revisit Chapter 4, “Math for 3D Graphics”, you’ll see that we’ve covered all the number crunching we’ll need here.

在置换贴图的例子中,我们所做的事情就是用一个纹理去使得一个平面进行偏移并且使用tessellation技术来增加场景中的几何形体的个数。这是一种比较简单粗暴的玩法。在cubicbezier的例子中,我们 将会使用数学知识来构建几何形体。如果你回顾一下第四章的内容,你将会看到我们如何来使用那些理论。

A cubic Bézier patch is a type of higher-order surface and is defined by control points that provide input to the interpolation functions that define the surface’s shape. A Bézier patch has 16 control points, laid out in a 4 × 4 grid. Very often (including in this example), those control points are equally spaced in two dimensions, varying only in distance from a shared plane. However, they don’t have to be. Free-form Bézier patches are an extremely powerful modeling tool being used natively by many pieces of modeling and design software. With OpenGL tessellation, it’s possible to render them directly.

一个cubic bezier patch是一种高阶曲面,它是由一些控制点来定义的,我们可以通过这些控制点插值出来几何体表面上的各个点。一个bezier patch有16个控制点,组成了一个4x4的网格。通常情况下, 那些控制点之间是等间距,变化的部分仅仅是到共享平面的距离。然而这并不重要。在建模软件中,自由形式的bezier patch是非常好的建模工具。通过OpenGL的tessellation技术,我们可以直接渲染出他们来。

The simplest method of rendering a Bézier patch is to treat the four control points in each row of the patch as the control points for a single cubic Bézier curve, just as was described in Chapter 4. Given our 4 × 4 grid of control points, we have four curves; if we interpolate along each of them using the same value of t, we will end up with four new points. We use these four points as the control points for a second cubic Bézier curve. Interpolating along this second curve using a new value for t gives us a second point that lies on the patch. The two values of t (let’s call them t0 and t1) are the domain of the patch and are handed to us by the tessellation evaluation shader in http://gl_TessCoord.xy.In this example, we’ll perform tessellation in view space. That is, in our vertex shader, we’ll transform our patch’s control points into view space by multiplying their coordinates by the model–view matrix. This simple vertex shader is shown in Listing 8.12.

就如同第四章介绍的那样,最简单的渲染bezier patch的方法就是把每一行的四个控制点都当成是一个cubic bezier曲线的控制点。如此一来,给我们4x4个控制点之后,我们就可以得到四条曲线。如果我们 对它们进行插值的都是使用同一个插值因子t,那么我们将会得到四个新的点。我们使用这四个点产生第二个cubic bezier曲线。在我们第二条cubic bezier曲线进行插值的时候,我们使用另外的一个t值进行插值,这样 我们就可以拿到第二批点。这俩t值是存在于patch领域下的,并且通过tessellation evaluation shader的gl_TessCoord.xy传给我们。在本例子中,我们在视口空间进行曲面细分。也就是说,我们的vertex shader中, 我们要把我们的patch的控制点都转到视口空间里来。清单8.12展示了我们的vertex shader。

#version 450 core
in vec4 position;
uniform mat4 mv_matrix;
void main(void){gl_Position = mv_matrix * position;
}

Listing 8.12: Cubic Bézier patch vertex shader

Once our control points are in view space, they are passed to our tessellation control shader. In a more advanced algorithm, we could project the control points into screen space, determine the length of the curve, and set the tessellation factors appropriately. However, in this example, we’ll settle for a simple fixed tessellation factor. As in previous examples, we set the tessellation factor only when gl_InvocationID is zero, but pass all of the other data through once per invocation. The tessellation control shader is shown in Listing 8.13.

当我们的控制点都转到视口空间下来了之后,他们将会被发送给tessellation control shader。在一些更进一步的算法中,我们可以把这些控制点投影到屏幕空间里去,这样就可以求得 曲线的长度,然后就可以设置合适的细分因子了。然而在本例子中,我们只是简单的设置一个固定的细分因子。如同前面的那些例子,我们仅当gl_InstanceID等于0的时候才去设置细分因子, 把其他数据简单粗暴的传给下一个shader阶段。清单8.13展示了tessellation control shader。

#version 450 corelayout (vertices = 16) out;
void main(void){if (gl_InvocationID == 0){gl_TessLevelInner[0] = 16.0;gl_TessLevelInner[1] = 16.0;gl_TessLevelOuter[0] = 16.0;gl_TessLevelOuter[1] = 16.0;gl_TessLevelOuter[2] = 16.0;gl_TessLevelOuter[3] = 16.0;}gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

Listing 8.13: Cubic Bézier patch tessellation control shader

Next, we come to the tessellation evaluation shader, which is where the meat of the algorithm is found. The shader in its entirety is shown in Listing 8.14. You should recognize the cubic_bezier and quadratic_bezier functions from Chapter 4. The evaluate_patch function is responsible for evaluating the vertex’s coordinate given the input patch coordinates and the vertex’s position within the patch.

下一步,我们来到tessellation evaluation shader里面了,在这里我们实现核心的算法部分。清单8.14展示了全部的代码清单。你应该可以看得明白cubic_bezier和quadratic_bezier 函数了,因为第4章介绍过的。evaluate_patch函数就是用来根据输入的patch的坐标和在patch里的那些点的位置来生成顶点的坐标的。

#version 450 core
layout (quads, equal_spacing, cw) in;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
out TES_OUT{vec3 N;
} tes_out;
vec4 quadratic_bezier(vec4 A, vec4 B, vec4 C, float t){vec4 D = mix(A, B, t);vec4 E = mix(B, C, t);return mix(D, E, t);
}
vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t){vec4 E = mix(A, B, t);vec4 F = mix(B, C, t);vec4 G = mix(C, D, t);return quadratic_bezier(E, F, G, t);
}
vec4 evaluate_patch(vec2 at){vec4 P[4];int i;for (i = 0; i < 4; i++){P[i] = cubic_bezier(gl_in[i + 0].gl_Position,gl_in[i + 4].gl_Position,gl_in[i + 8].gl_Position,gl_in[i + 12].gl_Position,at.y);}return cubic_bezier(P[0], P[1], P[2], P[3], at.x);
}
const float epsilon = 0.001;
void main(void){vec4 p1 = evaluate_patch(gl_TessCoord.xy);vec4 p2 = evaluate_patch(gl_TessCoord.xy + vec2(0.0, epsilon));vec4 p3 = evaluate_patch(gl_TessCoord.xy + vec2(epsilon, 0.0));vec3 v1 = normalize(p2.xyz - p1.xyz);vec3 v2 = normalize(p3.xyz - p1.xyz);tes_out.N = cross(v1, v2);gl_Position = proj_matrix * p1;
}

Listing 8.14: Cubic Bézier patch tessellation evaluation shader

In our tessellation evaluation shader, we calculate the surface normal to the patch by evaluating the patch position at two points very close to the point under consideration, using the additional points to calculate two vectors that lie on the patch and then taking their cross product. This result is passed to the fragment shader shown in Listing 8.15.

在我们的tessellation evaluation shader中,我们先根据patch中的两个点计算出这种条件下额外的一个点,然后用这额外的一个点构成2个在这个patch上的向量,然后叉乘出来法线。这个结果会传给 清单8.15展示的fragment shader。

#version 450 coreout vec4 color;
in TES_OUT{vec3 N;
}fs_in;
void main(void){vec3 N = normalize(fs_in.N);vec4 c = vec4(1.0, -1.0, 0.0, 0.0) * N.z + vec4(0.0, 0.0, 0.0, 1.0);color = clamp(c, vec4(0.0), vec4(1.0));
}

Listing 8.15: Cubic Bézier patch fragment shader

This fragment shader performs a very simple lighting calculation using the z component of the surface normal. The result of rendering with this shader is shown in Figure 8.14.

这个fragment shader根据表面的法线的z分量简单粗暴的计算出了光照。图8.14展示了渲染出来的结果图像。

Because the rendered patch shown in Figure 8.14 is smooth, it is difficult to see the tessellation that has been applied to the shape. The left side of Figure 8.15 shows a wireframe representation of the tessellated patch, and the right side of Figure 8.15 shows the patch’s control points and the control cage, which is formed by creating a grid of lines between the control points.

因为图8.14展示出来的渲染出来的patch比较光滑,所以很难看出细分效果。在图8.15中,我们在左边展示了线框模式下的结果画面,右边的图中我们展示了那些生成画面用的那些控制点,以及控制点之间的连线。

我们核心关注和讨论的领域是引擎的底层技术以及商业化方面的信息,可能并不适合初级入门的同学。官方相关信息主要包括了对市面上的引擎的各种视角的分析以及宏观方面的技术讨论,相关领域感兴趣的同学可以关注东汉书院以及图形之心公众号。

只言片语,无法描绘出整套图形学领域的方方面面,只有成体系的知识结构,才能够充分理解和掌握一门科学,这是艺术。我们已经为你准备好各式各样的内容了,东汉书院,等你来玩。

用-force –opengl 指令_OpenGL-使用Tessellation技术绘制Cubic Bézier Patches相关推荐

  1. 用-force –opengl 指令_苹果新系统ios14新功能汇总 轻点背面等小技巧怎么用

    在 iOS 14 以及更新系统中,苹果为 iPhone X 以及更新机型带来了"轻点背面"功能,可以让用户轻点手机背面来实现更多操作,并且这项功能还支持"快捷指令&quo ...

  2. 现代OpenGL教程(一):绘制三角形(imgui+OpenGL3.3)

    前言:imgui 是一个开源的GUI框架,自带的例子里面直接集成了glfw+gl3w环境,本例使用的版本是imgui v1.61,下载地址:https://github.com/ocornut/img ...

  3. 现代OpenGL教程(三):绘制彩色立方体(imgui+OpenGL3.3)

    前言:imgui 是一个开源的GUI框架,自带的例子里面直接集成了glfw+gl3w环境,本例使用的版本是imgui v1.61,下载地址:https://github.com/ocornut/img ...

  4. 视频教程-OpenGL实现Google地图瓦片的绘制漫游视频教程-软件设计

    OpenGL实现Google地图瓦片的绘制漫游视频教程 2004年毕业于西南科技大学,计算机科学技术专业,从事软件开发,游戏开发,擅长游戏开发,桌面应用,手机游戏. 张立铜 ¥208.00 立即订阅 ...

  5. OpenGL学习笔记(一)绘制点线面及多面体

    OpenGL学习笔记(一)绘制点线面及多面体 绘制点线面 #include <iostream> #include <GL/GLUT.h> #define PI 3.14159 ...

  6. 计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制

    实验一 VS+OpenGL绘图环境及基本图形绘制 一.实验目的 熟悉OpenGL的主要功能: 掌握OpenGL的绘图流程和原理: 掌握OpenGL核心函数的使用: 熟悉OpenGL基本图形元素的绘制函 ...

  7. openGL使用GLFW、GLEW库绘制点

    前言 openGL使用GLFW.GLEW库绘制点,下面这段代码:绘制蓝色背景,中心点是一个黄色的点,由于代码比较简单,所以我把顶点着色器和片元着色器硬编码到c++程序中.问题就在这!!!由于着色器都写 ...

  8. OpenGL 4.0的Tessellation Shader(细分曲面着色器)

    细分曲面着色器(Tessellation Shader)处于顶点着色器阶段的下一个阶段,我们可以看以下链接的OpenGL渲染流水线的图:Rendering Pipeline Overview - Op ...

  9. opengl 纹理贴到对应的位置_一步步学OpenGL(27) -《公告牌技术与几何着色器》

    教程 27 公告牌技术与几何着色器 原文: http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.html CSDN完整版专栏: https:// ...

最新文章

  1. golang import 导入包语法介绍 点 别名 下划线
  2. android javacv直播,无插件即时视频播放
  3. Android系统介绍
  4. python梯度下降法实现线性回归_梯度下降法的python代码实现(多元线性回归)
  5. 格雷码问题:输出当输入为n时的格雷码
  6. cvpr 深度估计_干货 | 2019 到目前为止的深度学习研究进展汇总
  7. Laravel 5 4 实现前后台登录
  8. ubuntu 刚更改默认python3版本后更新包等
  9. python turtle画房子详细解释_简述python的turtle绘画命令及解释
  10. mysql忘记root密码安装_MySql忘记root密码的解决方法
  11. 淘宝中的一些基本CSS代码
  12. itextpdf使用
  13. 引擎开发-图形渲染器开发
  14. 突发:史蒂芬·霍金去世,享年76岁!
  15. ED1 SoC Linux环境搭建
  16. ISO软件质量度量模型
  17. Pbootcms自定义分页样式,适用于多种环境
  18. JAVA基础作业练习—自定义异常之模拟ATM
  19. Python零基础入门,纯干货!
  20. 胭脂冷、碎玉楚碟烟花散

热门文章

  1. LeNet-5 经典卷积网络模型浅析
  2. Lodop客户端本地和集中打印 [是否安装][操作系统]
  3. ASP.NET GetPostBackEventReference
  4. Python MySQLdb 循环插入execute与批量插入executemany性能分析(list批量写法亲测成功)
  5. 梯度提升树(GBDT)原理小结
  6. 常见的网站服务器架构有哪些?
  7. linux下为php添加curl扩展的方法
  8. Git停止跟踪rm -r --cached与ignore区别
  9. MySQL加索引语句不加锁:ALGORITHM=INPLACE, LOCK=NONE
  10. Mysql翻转字符串reverse