游戏引擎学习第100天

仓库:https://gitee.com/mrxiao_com/2d_game_2

昨天的回顾

今天的工作重点是继续进行反射计算的实现。昨天,我们开始了反射和环境贴图的工作,成功地根据法线显示了反射效果。然而,我们还没有实现反射向量的计算,导致反射交点的代码未能运行。因此,目前显示的只是一个平面的效果,因为我们仅仅是验证了能否从环境贴图中进行查找,而并未实现实际的反射计算。

今天的目标是详细了解反射代码的工作原理,并尽可能实现它。通过这个过程,我们将继续推进法线贴图的代码实现,接下来要做的主要是优化这部分内容。在剩下的光照计算工作中,很多都涉及如何计算和采样环境贴图,因此反射代码的实现将是关键。

接下来的工作将集中在实现反射向量的计算以及相关代码的完成,接着进入到优化和其他细节的处理。

黑板:表面反射率

在今天的工作中,主要关注的是理解反射模型的数学原理,并试图实现这一点。部分内容比较直接,容易理解,另一些则稍显复杂,特别是在处理2D光照时需要做一些近似,因为无法直接实现某些计算。

首先,回顾一下前面的图示,我们讨论了光照和反射的过程。每个反射表面都有一个视点和一个光源,光源和视点形成一个“反射”的路径,类似于光线反射的行为。在高反射表面上,光线的反射会非常直接,反射光线的角度与入射光线的角度是相同的,这种反射被称为纯反射。

当表面反射能力较差时,反射光线会扩展成一个较大的光锥,意味着更多的光线会散射到反射表面。随着表面变得更加光滑,反射的光线会变得更加集中。这个模型并不是基于物理的光照模型,而是一个简化的近似。在实际应用中,大多数表面都可以通过这种近似来实现合理的效果,尤其是在2D图形中。我们通过简单的反射模型计算反射光线,或者通过模糊的纹理贴图来实现更广泛的反射效果。

最终,光照的核心目标是计算直接反射的光线,即从视点出发,反射光线沿着相同的路径返回。这是一个相对简单的反射模型,主要集中在如何计算这种反射光线,并逐步实现。

黑板:直线反射模型和碰撞检测

在碰撞检测中,使用的数学方法和光照模型中的反射计算相似。假设有一个表面,其法线向量为 n,且有一个从眼睛指向该表面的向量 e。为了计算反射向量,我们需要产生一个与向量 e 相似的向量,但方向相反。具体来说,这个反射向量的 y 分量保持不变,而 x 分量则取反。这个过程和碰撞检测中计算反射向量的过程非常相似。

假设我们有一个指向眼睛的向量 e,目标是计算一个采样向量 s。为了得到反射向量,首先需要对 e 进行取反,得到负的向量 -e。然后,可以通过一个几何构造来确定反射向量。首先,计算法线与向量 e 的点积,这样可以知道 e 在法线方向上的分量。接着,通过沿着法线方向加上这个分量的两倍,得到反射向量。

通过这种几何构造,反射向量就可以被有效地计算出来,避免了繁琐的代数推导。虽然可以通过代数方法求解这个问题,但几何方法通常更加直观且效率更高。

查看代码

在实现反射计算时,首先需要定义眼睛的视线方向向量(EyeVector)和表面的法线(Normal)。法线可以从法线贴图中获得,但视线向量在 2D 游戏中尤其难以定义,因为没有一个明确的“眼睛”位置或视线方向。在这种情况下,需要找到一种方法来推算视线向量。

代码中有一个待办事项,任务是基于观察者的视线方向来计算反射向量。为了实现这一点,需要通过代码获得法线向量,并且推算出一个对应的视线向量。这对于 2D 游戏尤为复杂,因为没有直接的视角或摄像头位置定义。因此,在计算反射时,需要额外的工作来确定视线方向。

黑板:正交投影

在 2D 游戏中,常见的问题是游戏画面并不是基于透视的。传统的 3D 游戏中,视角随着物体位置的变化会出现不同的透视效果,比如物体的不同面会根据位置的不同而有所变化。但在 2D 游戏中,通常采用的是正交投影,这意味着即使物体在画面上移动,其外观不会因为透视关系发生变化。举个例子,一棵树在屏幕的左右两侧看起来是一样的,这与透视不同,因为透视下物体的侧面会随着位置变化而不同。

为了处理视线方向,考虑到游戏使用的是正交投影,可以假设视线始终是平行于屏幕的。这意味着,无论屏幕如何滚动,视线的方向都不会改变,从而避免了视线反射随着物体位置变化而变化的情况。这样做的目的是保持视觉一致性,避免在视觉风格上混用透视和正交投影,这样会更符合游戏的整体视觉效果。

将Z轴设为眼睛向量

为了处理视线方向,假设 z 轴指向正上方,垂直于屏幕。这意味着视线(即眼睛的向量)始终朝向屏幕外的某个方向。通过这种假设,视线就会始终指向上方,回到视角的位置,而不受物体移动的影响。这种做法保持了游戏中的视觉一致性,使得所有物体的反射和显示效果不会因为视角的变化而产生不自然的错觉。
在这里插入图片描述

黑板:一个“过早的优化”

通过假设视线向量(眼睛向量)仅在 z 轴方向上有影响,可以进行一定的优化。因为在进行计算时,只有 z 坐标需要参与运算,这简化了运算的复杂度。例如,当计算点积时,由于 x 和 y 坐标的影响可以被忽略,最终只需要关注 z 坐标。这使得计算变得更加高效。

进一步地,可以考虑在法线贴图中直接存储 z 坐标的值,而不是存储完整的法线。这是因为已经知道法线的其他部分(x 和 y)对计算的贡献为零。因此,可以将法线贴图优化为只存储 z 坐标。尽管这样做可能有一些局限性,例如无法利用平方根技巧减少计算量,但这种做法仍然值得考虑。

假设眼睛向量始终为[0, 0, 1]来计算反射

在计算反射方向时,眼睛向量( I I I 向量)始终被假设为 (0, 0, 1),即指向屏幕外的 z 轴方向。为了计算反射,首先需要使用法线向量和公式进行计算。反射方向的 z 分量由法线的 z 分量乘以 2 得到,这个值与法线的 x、y、z 分量一起构成反射计算的一部分。

反射方向的计算过程可以简化为:通过法线向量的 z 分量进行加权,得到新的反射方向。然后,可以将这个反射方向传递到后续计算中。接下来,还需要处理屏幕空间的 UV 坐标,并计算与表面的交点。这些步骤涉及到反射的采样方向以及如何利用屏幕坐标信息来确定反射位置。
在这里插入图片描述

在这里插入图片描述

编译并查看结果

可以快速编译并查看结果,尽管这可能会导致非法结果,因此在实际运行时可能会出现断言错误,但还是决定尝试一下。结果没有出现断言错误,程序成功运行。可以看到,反射效果开始显现,但仍然没有完成正确的采样部分,距离最终效果还差一点。总体来看,反射效果开始有些圆润,表明数学运算没有出现大问题。
在这里插入图片描述

黑板:调整因子α

第二部分涉及一个“补偿因子”(fudge factor),这是一个相对麻烦的部分,因为它通常看起来似乎很合理,但实际上并不理想。补偿因子听起来很不错,特别是如果不是从字面上理解,而是指代某些旅游小镇出售的糖果那种“补偿因子”,因为糖果很好吃,但实际上它并不健康。真正应该考虑的是数学或物理中的“补偿因子”,而不是糖果。

补偿因子之所以不好,是因为它们没有明确的标准,你不知道它应该设定为多少,也不了解它的行为。使用真实世界的物理或数值时,通常知道它们应该是什么样子,如果出错就能定位到问题。然而,补偿因子通常是任意设置的,可能是设错了,导致调试变得困难。因此,虽然补偿因子是现实中不可避免的,甚至在最复杂的物理文献中也会出现,但它们的使用要尽量避免,尽量减少代码中的任意常量。

总之,虽然补偿因子在物理模拟中不可避免,但要尽量控制它们的使用,因为它们可能会带来调试和理解上的困难。

黑板:从环境贴图中采样

问题的核心在于屏幕上的一个点和该点在世界中的映射关系。假设屏幕是一个平面,我们有一个目标点,目标是通过从该点沿着某个方向投射来采样世界中的地图。现在的问题是,我们知道方向,但不知道应该走多远才能在这个方向上与地图相交。这个问题类似于碰撞检测中的光线与平面的交点问题,虽然之前已经做过类似的计算,但这里的困难在于没有明确的距离信息。

尽管我们可以通过设置一个大概的高度(比如设定天空在地面上的某个高度),但这种做法可能会在地图的边缘导致问题,因为边缘处的采样结果可能不准确。这个过程涉及到一定的"调节因子"(fudge factor),即如何处理这些不确定的变量,比如预设的天空高度等。

为了处理这个问题,首先假设我们知道Z轴上的位移距离(即光线在Z轴上的投射距离),然后通过计算在此方向上的位移量,得到X和Y方向上需要多少的位移。通过构建相似的三角形,我们可以计算出需要多少Z轴的位移才能到达目标位置,然后根据这个比例来确定X和Y轴的位移量。

当然,还需要考虑视角问题,比如是朝上看还是朝下看,这会影响Z轴的方向,因此需要根据不同情况调整计算。

总之,这个过程相对复杂,因为涉及到多个不确定的因素(比如调节因子),并且可能需要额外的调整,以确保在不同的屏幕对齐方式下能够正确采样。

假设反射方向始终与其尝试从中采样的地图方向一致

在处理反射方向时,目标是确保反射方向始终指向要从中采样的地图方向。假设所有的法线都是朝上的,我们将反射方向用作新的方向,而不是继续使用原来的法线。这时,反射方向将考虑当前实际观察到的方向。

具体来说,Y轴的值决定了反射是向上还是向下,因此反射方向的Y轴会告诉我们是朝上还是朝下采样。Z轴的值将与Y轴相对应,确定采样的方向。如果法线已经正确存储在适当的空间中,那么这部分的逻辑应该能够正常工作。

关键是要确保法线是正确配置的,并且反射方向能够正确指向目标地图。如果一切配置正确,反射方向的计算应该没有问题。

对底部地图取反反弹方向

在进行采样时,地图的法线图将基于反弹方向,而不是原来的法线,因为现在采样的方向才是关键。为了避免处理法线指向的方向(正Y或负Y),采样环境映射函数应该不需要关心法线的具体方向,而是始终假设Y轴是正值。这样,不论是在采样地面还是天空时,代码看起来应该一致,像是总是朝上采样。

具体来说,如果在采样时是从地面地图采样,法线的Y值应该为负;而从天空地图采样时,法线的Y值为正。因此,我们只需要调整反弹方向的Y值,确保其总是指向上方,这样可以避免反弹方向需要自己处理法线的朝向。

调整反弹方向的Y值后,它的方向会发生变化,但大小不受影响。此时,反弹方向就可以正确传递给环境映射采样函数,开始进行下一步的处理。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

开始设置采样方向

在这里,Y 分量决定了在采样过程中走多远,这是因为我们在编码这些地图时的方式。我们希望假设 Y 不可能为零。我们之所以知道 Y 不能为零,是因为在之前的代码中已经做了相应的处理,如果 Y 为零,意味着它指向了平面,我们会避免这种情况。只有当 Y 不为零时,才会沿着正确的方向进行采样。

我们可以断言 Y 的值大于零,并且不应该出现 Y 为零的情况。由于之前的代码已经处理了这些情况,因此不会出现 Y 为零的情况,这是我们希望确保的。

接下来,我们需要做的就是基于这些前提来继续执行采样操作。
在这里插入图片描述

计算从调整因子和系数的偏移量

首先,需要计算系数,该系数由以下几部分组成:

  1. fudge factor(调节因子)f,它的作用是控制距离的大小。假设我们初步设定为1米,这个值可能不是最佳的,但可以作为一个初始值。该因子用于计算后续的偏移量。

  2. 计算系数:该系数等于调节因子 f 除以 SampleDirection.y,这是为了确保按 y 方向的分量来调整偏移量。通过这种方式,可以计算出正确的偏移量。

  3. 偏移量:偏移量是系数乘以剩余的向量(即 x 和 z 分量)。根据样本的坐标系统,x 和 z 分量用于定义偏移的方向。对于法线,x 方向用于 x 分量,z 方向用于 z 分量,y 方向与坐标系统有关。

  4. 待处理问题:当前使用的是一种特定的编码方式,可能会出现需要反转某些方向(例如 z 方向)的问题。为了确保系统正确工作,未来可能需要对坐标系统进行调整,反转方向等操作。

这些步骤的目的是确保样本坐标和偏移量在正确的方向上,以便计算正确的反射或反弹效果。

计算tX和tY并(错误地)限制它们

首先,偏移量提供了从当前点到目标点的距离,这个距离是以米为单位的。接下来,计算时,需要考虑从屏幕空间的 UV 坐标开始,我们会利用这些 tx 和 ty 值进行采样操作。在这里,tx 和 ty 是以像素为单位的,所以我们需要先计算出相关的 RP 值,然后将其乘以实际的纹理大小。

具体步骤如下:

  1. 计算 U 和 V:需要将当前的 LOD 映射到适当的范围内。这一步涉及到计算 U 和 V 的偏移量,以便根据纹理的大小进行调整。

  2. 纹理坐标调整:接着,需要将 tx 和 ty 的值调整为纹理的大小。为了确保不越界,tx 和 ty 会被限制在 [0, 1] 范围内,这样就能避免越界采样。

  3. 边界处理:由于可能会采样到纹理之外,采用了 clamp(0, 1) 来保证采样始终在有效范围内,从而避免出现无效或错误的采样结果。

总的来说,这一系列操作确保了偏移量能够正确地应用到纹理采样过程中,同时避免了超出纹理范围的情况发生。
在这里插入图片描述

找到UV值

为了计算 UV 坐标,首先需要确定屏幕空间中的偏移量。然后,通过将偏移量与当前屏幕空间的位置结合,得到最终的 UV 坐标。需要特别注意的是,偏移量的单位是米,因此必须将米转换为 UV 坐标。这就需要一个“米到 UV”的转换因子,即每米多少个 UV 单位。

在实现时,可以通过将转换因子与偏移量相乘来完成这一步骤。这个因子通常需要根据纹理的大小进行调整。如果转换因子设置得过高,会导致 UV 坐标计算错误,因此需要通过调试来确定正确的因子值。

此外,UV 坐标需要进行限制(clamp),确保它们位于 [0, 1] 范围内,以防止超出纹理的有效区域。这一过程可能会涉及调整其他参数,直到 UV 坐标能够正确映射到纹理上。

为了进一步清晰理解计算过程,建议将“米到 UV”的转换因子命名为更具描述性的名称,如“DistanceFromMapInz”,以便更好地理解和调试。
在这里插入图片描述

在这里插入图片描述

在游戏中查看并引入一些运动

目前,反射效果已经初步实现,尽管还不完美,但能看到一些反射效果。接下来,将添加一些运动效果,以便更好地观察反射的动态变化。当前,反射看起来有些问题,尤其是在底部反射部分,可能是因为Y轴的翻转处理不正确,需要重新检查这一点。反射效果的优化还没有完成,目前的实现非常昂贵。

此外,反射效果的调试版本比较慢,编译器优化的提升可以改善性能,虽然在调试版本中,性能问题尤为明显。目前,反射已经开始动态变化,可以看到光线的反射效果,但底部的反射应当向另一个方向弯曲,这表明底部的翻转处理存在问题,需要进一步修正。

此外,采样时遇到的问题可能是因为边缘点的法线处理不当,可能是法线设置为直向后方,这可能导致了一些不正常的采样表现。在这些位置,可能没有正确处理球体外部的法线信息,这也需要修正。

反射的法线可能指向错误的方向,应该看到一些棋盘状的效果,但目前没有看到,这可能是一个 bug。反射的法线应当直接指向观察者,而不是指向天空。这样的问题源自于光照系统的处理,因为这是第一次进行此类光照处理,需要考虑如何正确编码光照计算和反射效果。
在这里插入图片描述

黑板:我们编码事物的方式

在光照计算中,法线的方向需要特别注意。当前,法线的设置为(0, 0, 1),表示它指向屏幕的z轴正方向,而这并不指向天空,而是指向一个特殊的采样平面。如果想要让法线指向“直上”,应该将法线的值设置为(0, 1, 0),而不是(0, 0, 1)。这意味着,在光照系统中,法线的方向设置不正确,可能导致反射效果的方向出现问题,需要进行修正。

更改MakeSphereNormalMap中的默认法线

在生成法线贴图时,默认法线方向的设置需要调整。目前的法线方向是指向屏幕的z轴正方向,而不是指向天空。为了使法线指向天空,应该将其设置为指向y轴的正方向,即(0, 1, 0)。这样可以更好地控制反射效果,提供更准确的光照模拟。调整默认法线后,重新生成纹理贴图,查看是否有改善。
在这里插入图片描述

在游戏中查看

目前的反射效果没有达到预期,尤其是在需要显示棋盘图案的区域。反射效果仍然不准确,可能是因为在模拟镜面反射时存在一些问题。具体来说,可能是反射表面上的球形着色没有正确处理,导致不符合预期的反射效果。为了找出问题的根源,需要进一步检查是否正确地使用了球体的alpha值,或者检查其他与反射和着色相关的部分,以找出为何没有显示预期的棋盘图案。
在这里插入图片描述

进入调试器β

当不确定问题的原因时,通常意味着需要进一步调试以学习更多的内容。为了理解当前反射效果的问题,首先查看了渲染调用,并通过绘制矩形来逐步进行调试。在采样法线贴图时,检查了计算出的法线,确认其确实指向天空,这是预期的结果。接下来,检查了反射方向的计算,以进一步了解计算过程是否正确。这些调试步骤有助于发现并解决潜在的问题。

黑板:我们仍然需要一些镜面的倾斜度

通过进一步思考,反射的方向解释变得更加清晰。如果法线完全指向天空,那么反射会呈现出一种与镜面平行的效果,相当于将镜子横着拿着观察,不会看到反射的效果。如果希望看到向上的反射,镜子仍然需要有一定的倾斜角度。因此,经过思考,这个现象其实是合乎逻辑的。尽管如此,仍然需要进一步调试其他部分以确保一切正常。

调整法线

通过将法线调整为半y半z的方向,经过标准化处理后,得到了期望的反射效果。具体而言,计算了 1 1 + 1 \frac{1}{\sqrt{1+1}} 1+1 1 的结果,并得到了指向上方并具有一定倾斜角度的标准化法线。这种修改符合预期,反射效果看起来更符合需求。
在这里插入图片描述

在游戏中查看反射球

反射效果已经逐渐接近目标,但仍然存在一些问题,反射代码还没有完全正确工作。目前,可以看到反射的效果已经开始出现,但仍需要一些调整才能完善。尽管离最终完成还有一定距离,但进展已经比较接近。接下来的工作将继续检查代码,特别是检查蓝色的代码部分,目的是搞清楚当前反射实现中的问题。如果今天无法解决这个问题,可能会把这个问题作为明天的工作重点。

考虑调查顶部地图的问题

当前问题在于顶图(蓝色的天空图)采样出现异常,导致反射效果不正确。反射代码似乎需要一些调整,特别是在计算反射路径时,可能需要做一些取反操作,但目前不确定为何需要这样处理。怀疑可能是反射计算过程中某个环节不够严谨,因此决定将问题的排查留到明天,仔细检查每个步骤,确保所有计算都是正确的。尽管如此,进展已经相当接近,问题很可能会很快得到解决。

你可以尝试创建一个具有更可预测反射的法线贴图,而不是使用球形的

当前反射效果仍存在问题,考虑到调试反射时,使用球形表面通常可以比较清晰地展示反射的全过程,因此决定尝试使用更具可预测性的法线图。可能考虑使用像波浪形的表面(上下起伏)作为替代方案,因为它能提供不同的反射模式,帮助更好地调试。另一个发现是反射衰减的现象,可能与环境图的混合系数有关,但由于法线是指向上的,理论上不应该发生这种情况,因此需要进一步思考并排查问题。总结来说,当前存在一些bug,计划在明天深入调试并解决这些问题。

法线贴图中的Y轴设置正确吗?

当前法线图的Y轴设置是反转的,意味着球体的顶部在底部,底部在顶部。之所以这样设置,是因为计划在坐标系统中进行翻转,因此在更改之前没有做调整。尽管从技术上来说,这与正常的坐标系统是反向的,但这种翻转只会影响反射的呈现方式,而不会影响其他反射的行为。换句话说,这只是导致蓝色出现在底部、红色出现在顶部,但除非有误,否则这不会对反射效果产生根本性影响。

一些人建议使用金字塔形

有提议考虑使用金字塔形状,金字塔的法线图是比较容易生成的。可以通过创建一个金字塔的法线图来实现,基本的思路是通过选择哪一部分设置为特定的法线值(例如0.777),金字塔的形状可以通过判断X是否大于Y来决定。也可以考虑其他形状,比如菱形,但金字塔形状相对直接。
在这里插入图片描述

黑板:金字塔

想要创建一个金字塔形状,首先需要定义金字塔的轮廓。金字塔的底部可以通过 x = y 的线来表示,而其顶部则是 1 - x = y 的线。在这种情况下,可以通过判断点是否位于这些线的哪一侧来确定其位置。如果 x 小于 y,那么这个点要么位于金字塔的一侧,要么位于另一侧。通过这种方式,可以简单地分类并确定每个点的归属,从而绘制出金字塔形状。这是一个比较直接的方法,完全可以实现。

制作金字塔

如果 x 小于 y,那么就意味着点位于金字塔的两个象限之一,否则就不在这些象限中。接下来,可以通过判断点是否满足 1 - x = y 的条件来确定其位置,虽然这个表达方式可能并不是最简洁的,但可以按这种方式处理。至于坐标系统,目前的坐标系统是反向的,但为了方便起见,仍然按正常方式处理,忽略这一点。

黑板:弄清楚金字塔的设置

实际上,考虑到金字塔的形状,x = y 线和 1 - x = y 线分别是确定各个区域的关键。如果 x 小于 y,那么就意味着点位于金字塔的某个象限,具体位置还需要判断是否满足 x 小于 y 的条件。对于每个区域,Z 坐标都等于 0.7,而 X、Y 方向的分量则会根据象限的不同而取不同的值:在 X 方向指向负值,在 Y 方向指向负值,反之亦然。这个逻辑看起来比较直接,可以按此处理。

设置金字塔

在计算金字塔形状的法线时,不需要使用 XY,也不需要其他复杂的计算,只需要直接根据条件确定法线的方向。通过判断 x < yindex < y,可以确定法线的方向。如果条件符合,法线的 x 分量为负值,表示该面朝向负方向;如果不符合,则根据位置调整法线的 yx 分量,以确定正确的方向。这种方法简化了代码,并减少了不必要的计算。
在这里插入图片描述

尝试一下

在讨论中提到需要调用 MakePyramidNormalMap 来生成一个金字塔形状。通过使用金字塔形状,发现 Y 轴上的两个点没有反射,可能是因为它们指向的方向没有指向任何物体,或者是其他未知的原因。这一问题需要进一步思考和调查。
在这里插入图片描述

在这里插入图片描述

提问:我认为底部的反射也需要翻转Y轴,因为这是输入向量,对吗?

可能需要翻转y轴的反射,但这并不完全正确。因为已经在之前的计算中考虑了入射向量的影响,特别是通过处理负的E向量和相关的计算,已经部分解决了这一问题。

你说过可能需要使天空贴图比地面更大,这样就不会错过它。能否从相邻的天空地图中采样(假设它们没有被遮挡)?

无法从相邻的天空贴图进行采样,因为在游戏中并不存在相邻的天空贴图。目标是生成一个照明效果,覆盖所需的采样范围。进一步提到,天空实际上类似于室内的天花板,因此需要保持动态性,以便适应不同的环境。

边缘衰减是正确的,因为从边缘反射的向量的Y值将比从中心附近反射的向量小

边缘衰减是正确的,因为反射向量位于边缘时,其y值会比靠近中心的反射向量更小。随着平面变得更加倾斜,反射向量的y分量会减少。当反射法线朝向y轴时,y分量将最大,尤其是在反射角度接近45度的位置。这是因为当反射法线正对着观察者时,y分量最大,而当反射变得越来越倾斜时,y分量逐渐减小。

提问:是否可以旋转“输入”采样,使得球体看起来在旋转?

可以通过为环境贴图添加偏移量来旋转进入的采样,从而使球体看起来像在旋转。事实上,不仅仅是旋转,也可以通过移动来实现。然而,这样做就不再是反射了,因为一个旋转的反射球体看起来和一个静止的反射球体一样。因此,需要小心处理这个效果,因为它不再保持原本的反射特性。

圆柱可能会有用

使用圆柱体代替当前的实现可能会更有效,圆柱体的使用是一个非常好的建议。为了调试一个问题,考虑添加圆柱体的法线图,其中X值始终存在,而Y值则可以被忽略。这种方法可能通过设置不同的参数来生成圆柱体,避免考虑Y分量,从而实现期望的效果。通过这种方式,生成的图形看起来像一个滚动的圆柱体。这也意味着原本生成金字塔的代码可能存在问题,需要进一步调试和修正。
在这里插入图片描述

在这里插入图片描述

你是使用左手坐标系还是右手坐标系?

在讨论中提到,屏幕空间采用的是右手坐标系,但目前仍使用左上角作为参考点。计划先完成法线图的相关工作,再处理剩余的任务。

法线贴图的反转版本会有用吗?(反转的球体)

提到法线图的反向版本,反向的球形法线图可能不适用于调试,但对于游戏玩法而言,使用反向法线图是可以的,当真正应用于游戏时可以考虑。

根据X/Y轴旋转法线!

目前没有进行法线的变换,这是接下来需要处理的一个问题。比如,观察到在旋转时,法线并没有正确地指向不同的方向,而是保持原来的指向。这意味着法线没有被正确地转换,因此需要确保在旋转过程中正确变换法线方向。明天的任务之一就是解决这个问题,并在代码中加入相应的注释。
在这里插入图片描述

在这里插入图片描述

提问:就此结束!

目前,正常贴图的调试工作已经接近尾声。接下来的任务是处理中间贴图,这将是一个更具挑战性的部分。虽然目前尚不确定解决方案,但希望能够找到一个巧妙的办法。明天将继续调试正常贴图的代码,直到完全解决,然后开始研究如何处理中间贴图。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16597.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac上搭建宝塔环境并部署PHP项目

安装Docker Desktop》搭建Centos版本的宝塔环境》部署PHP项目 1. 下载Docker for mac 软件&#xff1a;https://www.docker.com/ 或使用终端命令&#xff1a;brew install --cask --appdir/Applications docker 2. 使用命令安装宝塔环境的centos7系统&#xff1a; docker pul…

从肠道菌群到炎症因子:读懂疾病的预警信号

当我们的皮肤被轻微割伤或烧伤时&#xff0c;伤口周围区域可能会变得红肿、发热&#xff0c;甚至伴有疼痛&#xff1b;感冒时&#xff0c;喉咙痛、肿胀&#xff1b;不小心扭伤后&#xff0c;可能会肿胀、疼痛和僵硬…这些都与炎症相关。 炎症&#xff0c;作为身体对损伤或感染的…

83.在 Vue3 中使用 OpenLayers 利用 TLE 计算并显示单个卫星的轨迹

1. 前言 在可视化开发中&#xff0c;卫星轨迹的实时计算与展示是一个比较有趣的应用场景。TLE&#xff08;Two-Line Element Set&#xff09;是一种用于描述卫星轨道参数的格式&#xff0c;我们可以通过 satellite.js 解析 TLE 数据&#xff0c;并计算卫星在任意时间点的位置。…

Vue3(2)

一.Vue新特性 &#xff08;1&#xff09;defineOptions:主要是用来定义Options API的选项 背景说明&#xff1a;有< script setup >之前&#xff0c;如果定义props&#xff0c;emits可以轻而易举地添加一个与setup平级 的属性。但是用了< script setup >后&#…

π 的奥秘:如何用有理数逼近无理数?

本文将围绕有理数、无理数、连续统以及它们之间的深刻联系展开讨论&#xff0c;并结合具体的数学理论如康托尔区间套定理、戴德金分割、柯西施瓦茨不等式等&#xff0c;进行简要探讨 由于本文并未深入探讨&#xff0c;可能存在部分不严谨的地方&#xff0c;也欢迎各位进行纠正…

图书管理项目(spring boot + Vue)

想要该项目的话&#xff0c;就 jia 我&#xff0c;并在评论区给我说一下&#xff0c;只需要1元&#xff0c;我把整个项目发给你 jia微&#xff1a;18439421203&#xff08;名字叫&#xff1a;Bingo&#xff09; 运行图片&#xff1a;

131,【2】 攻防世界 catcat-new

进入靶场 &#x1f431; 点击图片时发现url处很可疑 想到文件读取 ../app.py # 导入 os 模块&#xff0c;用于与操作系统进行交互&#xff0c;例如文件操作、路径操作等 import os # 导入 uuid 模块&#xff0c;用于生成通用唯一识别码&#xff0c;常用于生成随机的密钥 imp…

NO.12十六届蓝桥杯备战|关系操作符|操作符连用|浮点数比较|练习2道(C++)

关系操作符 关系操作符介绍 ⽤于⽐较的表达式&#xff0c;称为“关系表达式”&#xff08;relational expression&#xff09;&#xff0c;⾥⾯使⽤的运算符就称为“关 系运算符”&#xff08;relational operator&#xff09;&#xff0c;主要有下⾯6个。 运算符描述>⼤…

.NET Web-静态文件访问目录浏览

一、Web根目录访问 创建wwwroot文件夹app.UseStaticFiles(); // 启⽤静态⽂件中间件url/路径 进行访问 二、Web根目录之外的文件 app.UseStaticFiles(new StaticFileOptions {FileProvider new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath,&qu…

【漏洞复现】Casbin get-users 账号密码泄漏漏洞

免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删除。…

PPDock:复旦大学团队研发的蛋白质-配体“盲对接“技术

PPDock: Pocket Prediction-Based Protein−Ligand Blind Docking 发表于Journal of Chemical Information and Modeling&#xff0c;第一作者为 Jie Du&#xff0c;通讯作者为 Manning Wang&#xff0c;研究团队来自复旦大学。该研究提出一种新的基于口袋预测的蛋白质 - 配体盲…

中间件-安装Minio-集成使用(ubantu-docker)

目录 1、安装docer 2、运行以下命令拉取MinIO的Docker镜像 3、检查当前所有Docker下载的镜像 4、创建目录 5、创建Minio容器并运行 6、SDK操作 FileUploader.java 1、安装docer 参考这篇&#xff1a;Linux安装Docker 2、运行以下命令拉取MinIO的Docker镜像 docker pull…

使用 Notepad++ 编辑显示 MarkDown

Notepad 是一款免费的开源文本编辑器&#xff0c;专为 Windows 用户设计。它是替代记事本&#xff08;Notepad&#xff09;的最佳选择之一&#xff0c;因为它功能强大且轻量级。Notepad 支持多种编程语言和文件格式&#xff0c;并可以通过插件扩展其功能。 Notepad 是一款功能…

Java 大视界 -- 区块链赋能 Java 大数据:数据可信与价值流转(84)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【Android开发】Android Studio汉化

前言 该插件是官方支持插件&#xff0c;未对任何软件进行修改和破解 Android Studio 是基于 IntelliJ IDEA 社区版开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于Android应用程序的开发。以下是为什么 Android Studio 能使用 IntelliJ IDEA 插件的原因&am…

七、I2C通信读取LM75B温度

7.1 概述 I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种同步、多主从、串行通信协议&#xff0c;由飞利浦公司开发&#xff0c;主要用于短距离通信&#xff0c;尤其在集成电路之间。 7.1.1 主要特点 两线制&#xff1a;仅需SDA&#xff08;数据线&#xff09;…

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层 1. 两个元素实现 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>纯 CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层</titl…

微信小程序医院挂号系统

第3章 系统设计 3.1系统体系结构 系统的体系结构非常重要&#xff0c;往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为微信小程序医院挂号系统&#xff0c;属于开放式的平台&#xff0c;所以在管理端体系结构中采用B/s。B/s结构抛弃了固…

开源堡垒机 JumpServer 社区版实战教程:一步步构建企业安全运维环境

文章目录 开源堡垒机 JumpServer 社区版实战教程&#xff1a;一步步构建企业安全运维环境一、访问JumpServer1.1 登录1.2 功能模块1.3 系统设置1.3.1 基本设置1.3.2 邮件设置 二、用户管理2.1 场景2.2 创建用户2.3 用户登录密码重置 三、资产管理3.1 准备工作3.2 登录控制台3.3…

小红书八股面经一份(JAVA开发)

1. zmysql索引结构 mysql索引底层采用的是b树的结构&#xff0c;一开始mysql的索引采用的是b树的结构&#xff0c;当数据量达到一定程度的时候&#xff0c;b树存在深度过大的问题&#xff0c;那么磁盘io次数就会飞速上升&#xff0c;导致查询效率慢。b树就很好的解决了这个问题…