热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

opengl旋转矩阵和纹理坐标相乘_OpenGLRotatingPoints

全球图形学领域教育的领先者、自研引擎的倡导者、底层技术研究领域的技术公开者,东汉书院在致力于使得更多人群具备内核级竞争力的道路上,将带给小伙伴们更多的公

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

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

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

Because points in OpenGL are rendered as axis-aligned squares, rotating the point sprite must be done by modifying the texture coordinates used to read the sprite’s texture or to analytically calculate its shape. To do this, you can simply create a 2D rotation matrix in the fragment shader and multiply it by gl_PointCoord to rotate it around the z axis. The angle of rotation could be passed from the vertex or geometry shader to the fragment shader as an interpolated variable. The value of the variable can, in turn, be calculated in the vertex or geometry shader or be supplied through a vertex attribute. Listing 9.34 shows a slightly more complex point sprite fragment shader that allows the point to be rotated around its center.

由于OpenGL在绘制点精灵的时候会按照轴对齐的方式去绘制四边形,所以如果你想旋转一个点精灵的话就必须要修改点精灵的纹理坐标或者去亲手计算它的形状。为了做到这一点,你可以简单粗暴的创建一个2D的 旋转矩阵,然后在fragment shader中使用它与gl_PointCoord相乘来让点精灵绕z轴旋转。输入的旋转角度可以从vertex shader或者是geometry shader中传入,然后插值得到。这样一来,这个变量的值就可以在 vertex shader计算得到或者geometry shader计算得到或者通过顶点的属性提供。清单9.34展示了一个相对更复杂一点的点精灵的fragment shader,它使得点精灵可以绕着它的中心点旋转。

#version 450 core
uniform sampler2D sprite_texture;
in float angle;
out vec4 color;
void main(void)
{const float sin_theta = sin(angle);const float cos_theta = cos(angle);const mat2 rotation_matrix = mat2(cos_theta, sin_theta, -sin_theta, cos_theta);const vec2 pt = gl_PointCoord - vec2(0.5);color = texture(sprite_texture, rotation_matrix * pt + vec2(0.5));
}

Listing 9.34: Naïve rotated point sprite fragment shader

This example allows you to generate rotated point sprites. However, the value of angle will not change from one fragment to another within the point sprite. That means sin_theta and cos_theta will be constant and the resulting rotation matrix constructed from them will be the same for every fragment in the point. It is therefore much more efficient to calculate sin_theta and cos_theta in the vertex shader and pass them as a pair of variables into the fragment shader rather than calculating them at every fragment. Here’s an updated vertex and fragment shader that allows you to draw rotated point sprites. First, the vertex shader is shown in Listing 9.35.

这个例子允许你去生成旋转的点精灵。然而,这个角度的值不会因为点精灵上所在像素位置的变化而变化。也就是说sin ——theta和cos_theta将是常量并且产生的结果旋转矩阵对于每个点上的所有像素来说都是一样的。 因此,相比在fragment shader中进行计算,在vertex shader中计算出sin_theta和cos_theta的值然后把它们传入fragment shader会更加的高效。下面展示了新版本的vertex shader和fragment shader的代码。首先, 清单9.35展示了vertex shader的代码。

#version 450 core
uniform matrix mvp;
in vec4 position;
in float angle;flat out float sin_theta;
flat out float cos_theta;
void main(void)
{sin_theta = sin(angle);cos_theta = cos(angle);gl_Position = mvp * position;
}

Listing 9.35: Rotated point sprite vertex shader

Next, the fragment shader is shown in Listing 9.36.

紧接着,清单9.36展示了fragment shader的代码

#version 450 core
uniform sampler2D sprite_texture;
flat in float sin_theta;
flat in float cos_theta;
out vec4 color;
void main(void)
{mat2 rotation_matrix = mat2(cos_theta, sin_theta, -sin_theta, cos_theta);vec2 pt = gl_PointCoord - vec2(0.5);color = texture(sprite_texture, rotation_matrix * pt + vec2(0.5));
}

Listing 9.36: Rotated point sprite fragment shader

As you can see, the potentially expensive sin and cos functions have been moved out of the fragment shader and into the vertex shader. If the point size is large, this pair of shaders performs much better than the earlier, brute-force approach of calculating the rotation matrix in the fragment shader.

如你所见到的一样,sin和cos函数已经从fragment shader中移到了vertex shader中去了。如果点的大小很大的话,这组shader的性能相对于之前的那个简单粗暴的在fragment shader中计算旋转矩阵会更好一点。

Even though you are rotating the coordinates you derived from gl_PointCoord, the point itself is still square. If your texture or analytic shape spills outside the unit diameter circle inside the point, you will need to make your point sprite larger and scale your texture coordinate down accordingly to get the shape to fit within the point under all angles of rotation. Of course, if your texture is essentially round, you don’t need to worry about this at all.

即便你旋转从gl_PointCoord中推导出来的纹理坐标,点精灵本身依然是一个矩形。如果你的纹理或者形状玩到了点精灵的外面,你需要把点精灵弄大一点并且给它一个缩放,让它的形状适应当前点精灵的旋转角度。当然 如果你的纹理基本上是个圆的的话,你不需要担心这个事情。

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

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



推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
author-avatar
mobiledu2502875393
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有