游戏引擎学习第102天

发布于:2025-02-15 ⋅ 阅读:(12) ⋅ 点赞:(0)

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

改一下vscode clangd settings.json配置

要在 CMake 中生成 compile_commands.json 文件,可以通过设置 CMAKE_EXPORT_COMPILE_COMMANDS 选项为 YES 来实现。这个文件包含了所有编译命令,通常用于代码分析、IDE 支持等。

具体步骤如下:

  1. 在项目根目录中创建或修改 CMakeLists.txt 文件,确保包含以下行:

    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
    
  2. 或者,可以在运行 cmake 命令时通过命令行选项启用该功能:

    cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
    
  3. 然后,CMake 将在构建目录下生成 compile_commands.json 文件。

该文件会列出所有的编译命令,包括源文件、编译器选项和编译命令路径等,可以帮助工具(如 Clangd、VS Code、Sublime Text 等)进行静态分析、自动补全和错误检测等操作。

compile_commands.json 文件是一个 JSON 格式的文件,包含了项目中每个源文件的编译命令和相关信息。它的主要作用是提供给各种开发工具(如静态分析工具、IDE、代码补全工具等)准确的编译信息,帮助它们更好地理解代码的结构和依赖关系。

具体来说,compile_commands.json 的作用包括:

  1. 代码分析工具:静态分析工具(如 clang-tidycppcheck 等)需要知道每个源文件是如何编译的,包括编译器选项、宏定义、包含路径等。compile_commands.json 提供了这些信息,使得这些工具能够进行准确的代码分析和检查。

  2. IDE支持:一些集成开发环境(IDE),如 VS Code、Sublime Text、CLion 等,利用 compile_commands.json 来提供代码补全、跳转到定义、错误检查等功能。这使得 IDE 能够理解项目的编译环境,提供更智能的编辑支持。

  3. 编译器诊断:工具如 clangd 可以读取 compile_commands.json 来提高诊断的准确性,避免错误地解析代码。例如,它能根据正确的编译选项来分析语法和语义,从而生成更精确的警告和建议。

  4. 跨平台支持compile_commands.json 文件允许工具在不同的系统和平台上使用相同的编译配置进行分析。这对于跨平台项目尤其有用,确保在不同操作系统和编译器上的一致性。

  5. 调试和构建优化:一些构建工具和调试器可以读取 compile_commands.json 文件来优化构建过程或调试过程,确保它们使用正确的编译命令来构建每个文件。

compile_commands.json 文件的结构

该文件包含一个 JSON 数组,每个元素表示一个编译命令,结构大致如下:

[
  {
    "directory": "/path/to/project",   // 编译命令的工作目录
    "command": "clang++ -c -o file.o file.cpp -I/path/to/include",  // 编译命令
    "file": "/path/to/project/file.cpp"  // 编译的源文件
  },
  {
    "directory": "/path/to/project",
    "command": "g++ -c -o file2.o file2.cpp -I/path/to/include",
    "file": "/path/to/project/file2.cpp"
  }
]
  • directory:表示编译命令的工作目录。
  • command:是具体的编译命令,包括编译器、源文件、编译选项等。
  • file:是编译的源文件路径。

总之,compile_commands.json 文件是构建和开发工具之间共享编译信息的重要桥梁,有助于提升开发效率和代码质量。

在这里插入图片描述

在这里插入图片描述

昨天遇到了一些问题

过程中没有使用现成的游戏引擎或库,完全依靠自己的力量。目标是全面展示游戏开发中的各个方面,从如何绘制像素,到游戏 AI 等高级层面,观众能够了解游戏开发的每一个细节。

在昨天遇到了一个问题,难以解释如何转化法线(normals),而不深入讨论复杂的矩阵数学。

黑板:想象一个房子的法线

在这里讨论的内容是关于法线(normal)的转换。通过一个简单的例子来讲解,假设要绘制一座房子,房子是一个精灵(sprite)。首先,显示的是房子的位图,也就是实际绘制在屏幕上的房子。房子有 x 轴和 y 轴,按照这个坐标系绘制房子的图像。

然后,假设我们需要为这座房子创建一个法线图。比如,如果想要指出房子的一侧,可以想象将法线从屋顶的一点指向外部。为了找到这个法线,可以设想有两个点 p0 和 p1,p1 在上方,p0 在下方,取从 p0 到 p1 的向量。

通过这个向量,可以定义法线。法线是与屋顶平面垂直的向量,这是法线的基本定义。虽然这是一个二维的例子,但这个概念可以很容易地扩展到三维,因为在实际的流媒体中,处理的并不是三维旋转或细节,只是简单地对精灵进行缩放和旋转。因此,这个法线的计算在三维空间同样适用。

接下来可以用一个简单的公式来计算法线。通过取从 p1 到 p0 的向量(即 v),然后计算这个向量的垂直向量,就可以得到法线。

黑板:回顾如何得到一个向量的垂直向量

在之前的讨论中,已经提到如何获得一个向量的垂直向量。如果给定一个向量,其分量为 v x v_x vx v y v_y vy,那么其垂直向量可以通过交换这两个分量并对其中一个分量取反来得到。

具体来说,假设有一个二维向量 ( v x , v y ) (v_x, v_y) (vx,vy),其垂直向量的计算方法如下:

  1. v x v_x vx v y v_y vy 交换位置;
  2. v y v_y vy 取反,得到新的垂直向量 ( − v y , v x ) (-v_y, v_x) (vy,vx)

这是因为,在二维平面中,一个向量的垂直向量可以通过旋转 90 度来得到。旋转 90 度后的向量,其新坐标是交换 x x x y y y 坐标的位置,并对其中一个坐标取反。这是通过简单的坐标变换实现的,并且不会改变向量的大小,只是改变其方向。

另外,也可以有另一个垂直向量,方向与第一个相反。这个垂直向量是顺时针旋转 90 度得到的,其计算方式是交换坐标并对 x x x 坐标取反,得到 ( v y , − v x ) (v_y, -v_x) (vy,vx)。因此,实际上,对于任何二维向量,都有两个垂直向量,一个是逆时针旋转 90 度得到的,另一个是顺时针旋转 90 度得到的。

这两个垂直向量的大小和方向相同,只是方向相反,因此可以根据需要选择一个来使用。

黑板:通过旋转和均匀缩放构造法线

在之前的讨论中,已经介绍了如何通过构建垂直向量来生成法线。生成法线的过程是从给定的向量(如屋顶的向量)出发,通过求得其垂直向量,来得到法线。而如果将这些法线保存成法线贴图(normal map),我们就可以在之后对物体进行旋转时,保持法线的正确方向。

当需要旋转法线贴图时,旋转的过程与对物体上其他点的旋转类似。如果我们要旋转一个物体,我们会对每个点的坐标进行标准的旋转变换。例如,假设有两个点 p 0 p_0 p0 p 1 p_1 p1,它们的坐标可以通过与坐标轴的乘积来表示:
p 0 = p 0 . x × x axis + p 0 . y × y axis p_0 = p_0.x \times x_{\text{axis}} + p_0.y \times y_{\text{axis}} p0=p0.x×xaxis+p0.y×yaxis
p 1 = p 1 . x × x axis + p 1 . y × y axis p_1 = p_1.x \times x_{\text{axis}} + p_1.y \times y_{\text{axis}} p1=p1.x×xaxis+p1.y×yaxis
这些点会根据旋转矩阵进行变换,得到新的位置。在法线的情况下,由于法线本身没有具体的位置,它只表示一个方向,所以旋转法线时,只需要将法线应用同样的旋转变换,即可得到新的法线方向。

如果只涉及旋转操作,法线贴图并不需要做任何额外的处理。只需使用与之前相同的算法,就能根据新的旋转矩阵计算出新的法线方向。这样,法线会随着物体的旋转而正确变换。

如果进行缩放操作,假设对物体进行均匀缩放(例如,x轴和y轴都缩放为原来的两倍),法线的方向也不会受到影响,因为均匀缩放不会改变法线的方向。在这种情况下,法线仍然需要进行归一化处理,确保其长度为1。由于已经有相关代码处理法线归一化,因此均匀缩放不会对法线的计算产生问题。

总结来说,对于旋转和均匀缩放的情况,法线贴图可以使用与其他坐标变换相同的算法来处理,旋转时法线会正确地改变方向,而均匀缩放时,法线的方向保持不变,只需要归一化即可。

黑板:如果做非均匀缩放会发生什么?

当涉及到非均匀缩放时,会出现一些问题,尤其是法线的变换问题。假设我们有一个房屋模型,并且对其进行非均匀缩放。具体来说,如果对 x 轴进行大幅度的拉伸,而 y 轴不变,最终得到的形状将会是一个沿 x 轴拉长的房屋。

在这种情况下,法线的行为会与物体的点发生相反的变化。我们可以将法线视为原点处的一个向量,假设它最初与某个向量成 45 度角。当我们沿 x 轴进行缩放时,直觉上,我们会认为法线应该向下偏转,更接近水平。但实际上,正确的法线应该指向更高的方向,而不是向下偏移。

问题出在,如果我们直接使用相同的变换来处理法线,那么变换后的法线方向就会错误。原因是,法线是垂直于物体表面的向量。当物体的表面被非均匀缩放时,法线的方向也会受到影响,尤其是被拉伸的轴会导致法线的变化。

具体来说,假设我们有一个向量 v v v,它与法线 n n n 之间是垂直的。通过缩放 x 轴, v v v 向量的 x 分量会被拉长,从而导致法线的 y 分量发生变化。比如,如果我们将 x 轴缩放两倍,那么法线的 y 分量会被拉伸,从而导致法线方向的错误偏移。

在进行非均匀缩放时,法线的计算需要特别注意。因为法线是垂直于表面向量的,它会受到缩放变换的影响,并且这种影响是垂直的。如果忽略这一点,处理后的法线会导致不正确的反射效果,影响渲染效果。

因此,在进行非均匀缩放时,法线的变换需要特别处理,确保法线方向的正确性,否则可能会导致视觉上的错误,尤其是在光照和反射效果中。

黑板:我们如何绕过这个不正确的计算?

为了处理法线在非均匀缩放下的变换问题,需要特别注意法线的缩放方式。首先,法线是在法线贴图中以原始状态保存的,也就是说,法线的编码没有进行任何变换,它反映的是艺术资产的原始状态。问题出在,当进行非均匀缩放时,直接使用简单的向量变换(比如 n x × x + n y × y n_x \times x + n_y \times y nx×x+ny×y)会导致错误的法线方向,因为缩放操作会改变法线的方向。

因此,不能直接交换坐标轴,也不能仅仅依赖于标准的法线变换公式,因为这些会错误地旋转法线,而旋转本身是正确的。正确的做法是,在处理法线时,应该对缩放进行特殊的处理。具体而言,可以通过如下步骤来处理:

  1. 保持旋转不变:我们需要保留法线的旋转方向,避免对法线方向的任何不必要的旋转。
  2. 缩放处理:对于非均匀缩放的情况,我们需要将法线的每个分量按比例进行缩放。这意味着,对于 x 轴和 y 轴分别进行缩放时,法线的 x 和 y 分量的大小应该根据缩放后的轴的长度进行调整,而不是直接进行简单的比例转换。
  3. 归一化:将法线归一化,并确保缩放操作仅影响法线的大小,而不改变其方向。

具体而言,法线的计算公式应该是:

  • n x × ∣ y ∣ ∣ x ∣ × x n_x \times \frac{|y|}{|x|} \times x nx×xy×x
  • n y × ∣ x ∣ ∣ y ∣ × y n_y \times \frac{|x|}{|y|} \times y ny×yx×y

其中, l x l_x lx l y l_y ly 分别是缩放后的 x 轴和 y 轴的长度。通过这样的调整,法线的方向能够保持正确,同时缩放的影响也得以正确处理。

如果是均匀缩放(即 x 轴和 y 轴的缩放比例相同),那么缩放系数将会是 1,法线的变换就会恢复到原来的状态,公式也就变回了原始的简单变换。

当进行这种变换时,重要的一点是要确保法线的计算过程能够正确反映缩放后的变化。为了做到这一点,可以使用逆转置矩阵运算来实现这种对法线的特殊变换。这个操作会确保在缩放时,法线的方向不被影响,只会改变其长度。

看看目前游戏中发生了什么

在渲染组的过程中,需要绘制矩形。此时,出现了一个问题:我们尝试让一个小物体进行旋转,但发现旋转效果不正确,法线的反射没有如预期那样改变。这意味着法线在旋转时没有正确地更新,导致图像显示的反射效果不正确。

为了解决这个问题,必须在计算法线时进行调整。特别是在从法线贴图中提取法线时,需要确保法线的旋转效果得到了正确的处理。通过重新审视法线的变换方式,可以开始修正旋转过程中的错误,确保法线的旋转和反射效果一致。
在这里插入图片描述

基于X/Y轴旋转法线

在进行法线变换时,首先需要注意的是,法线的旋转应该在归一化之前进行。因为我们更关心的是法线的方向,所以不需要在旋转之后多次归一化,实际上只需要在旋转完成后进行一次归一化。这样可以简化处理过程。

具体来说,在旋转法线时,尽管法线是三维的,包含 x、y 和 z 三个分量,但由于旋转只影响 x 和 y 轴,z 轴的分量不会受到影响。因此,实际上只需要对 x 和 y 的分量进行旋转变换,而不涉及 z 轴的旋转。

为了实现这一点,旋转的计算过程是基于 x 和 y 轴的变换进行的。在代码中,通过将法线的 x 和 y 分别与 x 轴和 y 轴进行乘积运算,完成旋转变换。此时需要确保计算过程中,使用了与黑板上讨论的一致的系数,特别是 y 轴的长度与 x 轴长度的比例,以及 x 轴长度与 y 轴长度的比例。

在实际编码时,计算出的这些系数被称为 r x r_x rx r y r_y ry,其中 r x r_x rx 是与 x 轴相关的系数, r y r_y ry 是与 y 轴相关的系数。这些系数最终会用来调整法线的方向,确保法线经过旋转后,仍然保持正确的方向,最终实现正确的旋转效果。
在这里插入图片描述

引入NxAxis和NyAxis

在计算法线变换时,首先需要计算 x 轴和 y 轴的长度,并确保这些值正确。对于法线的 x 分量变换,需要使用 y 轴长度与 x 轴长度的比值,而对于法线的 y 分量变换,则需要反转这个比值。需要注意的是,这些计算得到的系数是常数,不需要每个像素重新计算,而是可以在运行时提前计算好,并将它们存储在轴本身。

为了优化这一过程,可以将这些系数直接“烘焙”到 x 轴和 y 轴上,使得法线的变换变得更为简洁。具体来说,可以在变换过程中创建一个“NxAxis”和一个“NyAxis”,这两个轴存储的就是这些系数。这样,最终的变换就只需要进行一次乘法操作,使用这些已计算好的系数即可,避免了每次计算时重复计算轴的长度。

通过这种方法,计算过程变得更加高效,同时也便于优化,比如在后期可以将这些常用的系数提取出来,减少不必要的计算。
在这里插入图片描述

给我们的v4增加仅分配xy、yz或zw的能力

当前的向量 v 还没有实现直接对 x, yy, z 等分量进行赋值的功能,因此需要对其进行改进。为了更好地操作向量,建议将这些操作集成到向量内部。这样,可以直接处理不同的向量分量,如 x, yy, z,并且使得向量操作更为方便和高效。

为了实现这一点,可以在代码中添加相应的功能,处理这些特定的分量,例如 y, zw 等。这将使得向量操作更加灵活,且符合需求。完成这些改动后,需要验证这些改动是否能够正确工作。
在这里插入图片描述

在游戏中检查一下

看起来结果并没有达到预期。因此,需要暂停一下,仔细检查之前的操作,找出哪里出了问题。
在这里插入图片描述

发现时刻:我们不能仅仅在调整Z轴大小后再归一化

有一个问题是,归一化操作会影响所有的大小,但不会正确地调整Z轴的大小。如果只进行归一化,就会导致问题,因为虽然X轴和Y轴的尺寸受到了影响,但Z轴的尺寸没有受到相应的调整,这会导致不对称的情况。

补偿X和Y的大小变化

在这里,需要对法线的z分量进行缩放,以补偿x和y轴变化后的大小差异,确保它正确地进行缩放。然而,目前不确定应该使用什么样的处理方式来进行这个调整。可以考虑让用户自定义如何处理这个问题。

一种可能的方案是,使用x轴和y轴的长度的平均值来计算z轴的缩放因子。例如,计算x轴和y轴的长度,然后将其作为z轴的缩放因子。可以将此因子称为NzScale,然后使用它来调整z轴的大小。

另外,忘记在代码中使用x轴的变量了,需要进行修正。
在这里插入图片描述

在这里插入图片描述

在游戏中查看

目前理论上已经正确地处理了旋转问题。虽然很难完全确认是否正确,但至少现在可以看到,当物体旋转到侧面时,颜色会逐渐淡出,这符合预期。因为当物体旋转时,它会指向地图上尚未使用的区域(类似于围绕物体的映射)。此外,还可以看到红色部分位于顶部并保持在顶部,这也是正确的。

之前红色部分会随着物体的旋转而变化位置,可能会出现在顶部或底部。现在至少能够看到,物体的旋转处理比之前更加准确,已按预期正确执行。

黑板:解释NzScale

在进行变换后,法线会出现一个缩放的问题,尤其是在处理 x 和 y 轴时,变换可能导致法线变得比实际应该的要大。例如,原本长度为 1 的法线经过变换后,可能会变得非常大,比如长度变为 100。这会导致法线的长度不再是标准化的,从而使得基于标准化的数学计算失效。

为了解决这个问题,需要确保法线的长度为 1,这就是为什么会使用标准化函数(normalize)。标准化操作将法线的每个分量除以法线的长度,确保其长度为 1。但问题出在,当进行变换时,只对 x 和 y 分量进行了缩放,z 分量并未缩放,因此 z 轴的长度可能没有得到正确的处理。

为了补偿这个问题,必须考虑到在三维空间中,法线的 z 分量应该与 x 和 y 的缩放保持一致。如果只是对 x 和 y 进行缩放,而 z 不变,就相当于将物体变得更宽更高,但深度几乎没有变化。标准化时,这样的法线会变得过于偏向 x 和 y 分量,而忽略了 z 分量。

为了修正这一点,应该在变换时对 z 分量进行适当的缩放,使其与 x 和 y 的缩放保持一致。理想情况下,用户可以指定如何沿各个轴进行缩放,这样法线就能正确反映变换的程度。特别是对于像圆柱体这样的物体,z 轴的缩放就是决定圆柱在深度方向上延展程度的关键。

在均匀缩放的情况下,x 轴、y 轴和 z 轴的长度应该相等,这就是所说的比例缩放。在这种情况下,法线的处理会变得更加自然和一致。

考虑NzScale

在这里,z 轴的缩放是通过设置 x 轴和 y 轴的长度来确定的。如果 x 轴和 y 轴的长度相同,那么 z 轴的缩放值也会一致;如果它们不同,则会取一个平均值,假设 z 轴也按这个比例缩放。但如果以后需要更精确的调整,特别是在游戏中进行动画时,可以将这个 z 轴的缩放作为一个参数,让用户可以控制 z 轴的缩放程度,以便根据具体需求进行细微调整。

继续正确地从地图中进行采样

目前需要回过头来检查之前的一些问题,尤其是确保从其他贴图中正确采样。先前的球体渲染还存在一些问题,需要进一步检查。一个观察到的现象是在球体边缘出现了闪烁的反射效果,可能是由于边缘的反射模式不太对,或者是计算过程中存在数值误差,像是除以零等问题。要确保这些问题没有导致异常结果。

虽然存在一些疑问,但球体旋转后的法线变换似乎运作良好,旋转后的球体反射效果保持稳定,这表明法线变换在旋转过程中是正确的,确保了球体的反射效果不会因为旋转而发生变化,这是预期的行为。接下来,将继续检查渲染的细节,找出并解决可能的问题,尤其是在反射和法线计算上。
在这里插入图片描述

在这里插入图片描述

简要记录一下SampleEnvironmentMap

代码主要涉及环境贴图采样。首先,代码使用屏幕空间的坐标来确定光线投射的位置,这个坐标是经过标准化的。接下来,采样方向(sample direction)决定了光线的传播方向,理论上应该是标准化的,但经过检查后发现,实际上它不一定需要标准化,因为在计算过程中会进行缩放,保证距离比例是正确的。因此,采样方向的长度不必为单位长度。

然后,根据粗糙度(roughness)来选择要采样的环境贴图。当前实现中,只支持选择第一个环境贴图,而其他的预设图集(LOD)尚未初始化,因此不会被采样。接下来,代码计算到贴图的距离,并且期望y值为正,确保光线总是朝着同一方向投射。为了更灵活地处理这个问题,可以考虑将z轴的距离作为参数传入,从而允许用户控制距离的方向,例如传入负值来进行反向映射。
在这里插入图片描述

将DistanceFromMapInZ传递给SampleEnvironmentMap

为了改进这个过程,可以将 DistanceFromMapInZ 作为参数传入,而不是依赖于固定的方向。这将消除当前的方向限制,使得可以根据法线实际指向的方向来采样地图。这样可以更加灵活地处理采样过程。为了实现这一点,可以定义一个新的变量 DistanceFromMapInZ,并考虑到在 y 方向上的使用,因为 y 方向在这里是关键。

黑板:思考2D游戏中光照的奇怪性质

在大多数游戏中,包括这款游戏,地面是平的,因此看起来像是从顶部俯视地面上的物体。然而,实际上,物体的存在并不是这种情况。在光照计算中,即使法线指向某个方向,光照却是照射在实际位置上,而这个位置位于 z 轴上方。这种情况会导致一些虚假的转换效果,即使方向指向屏幕外部的某个地方,光照的效果仍然是从地面以上的区域来的。这种设计对于2D游戏来说非常麻烦,因为它的艺术呈现方式与现实世界的物理规则相去甚远,因此必须在代码中做出一些不太符合常规的调整。
在这里插入图片描述

翻转DistanceFromMapInZ

实际上,所改变的是距离或映射的 z 值,这也意味着我们的地面贴图和天空贴图可以有不同的距离。这就是为什么做出这个调整的原因,因为现在可以独立地移动它们,避免它们必须同时移动相同的距离。这种方式可能会很有用。
在这里插入图片描述

在这里插入图片描述

确保我们在游戏中的位置没变,继续验证SampleEnvironmentMap

在这段代码中,首先计算了到地图的距离,同时将地图单位从米转换为用户期望的单位(可能是“用户单位”)。这是通过将地图距离和单位缩放结合在一起实现的。然后,代码继续计算交点,检查有效范围,并通过线性插值进行采样。使用用户单位来进行这些计算。

代码的整体结构看起来很干净,没有显著的错误,函数逻辑也很简单。虽然计算方向的 SampleDirection.x 是明确的,但 SampleDirection.z 是否应该反转仍然是一个值得探讨的问题。这涉及到坐标系统如何确定,尤其是 z 轴的使用。

目前的假设是,系统采用自下而上的坐标系统(“bottom-up”),这意味着 z 轴应该沿着地图的内外方向移动。进一步的讨论将涉及明确如何在地图中采样,确保 z 轴在合适的方向上进行计算。

黑板:弄清楚Z在地图中应该在哪个方向进行采样

在这段讨论中,考虑了一个球体的反射问题。假设球体的两侧反射出的方向不同,反射向量的 z 分量会根据角度变化。当反射角度小于 45 度时,反射向量的 z 分量仍然为正;但一旦反射角度超过 45 度,z 分量就会变为负值。

进一步讨论时,假设地面地图的 z 轴范围从负值到正值,如果球体的反射方向被视为正方向,则会出现反射方向和地面映射方向不一致的问题。具体来说,反射向量的 z 分量应该被取反,这样才能正确地与地面地图进行匹配。因此,反射的 z 值应该进行取反操作,以保证正确的方向性。
在这里插入图片描述

将BounceDirection.z推到头部并在那里取反

应该在后续阶段对反射方向的 z 值进行取反操作,而不是在当前阶段进行更改。具体来说,当处理反射方向时,应该将 z 值取反,即“反弹方向的 z 等于负的反弹方向的 z”。此外,还提到需要支持两种不同的映射方式:一种是顶视图(top-down view),另一种是侧视图(sideways),目前系统仅支持侧视图,顶视图的处理还未实现。
在这里插入图片描述

在游戏中查看,尝试翻转并调查发生了什么

当前遇到的问题是关于反射方向变化的行为。原本预计反射方向不会引起曲率变化,但事实证明反射方向的变化确实影响了曲率。这种变化令人困惑,因为地图是对称的,按理说反射方向不应改变曲率。反射的 z 方向被反转时,期望的效果是,采样方向的 z 轴值应与地图上的位置相匹配。

然而,反射后曲率的变化与预期不同,可能是由于反射方向的影响。虽然原本认为反射只是改变采样的 y 轴方向,但似乎它也改变了我们在地图上的位置,导致曲率发生了不应有的变化。

反射方向改变了从地图上采样的角度,可能引起了一个视觉上的误差,尽管地图上没有明显的变化。反射的 z 方向反转改变了地图采样的步伐,从而影响了视觉效果,尤其是在 y 轴方向。虽然期望地图应该保持不变,但实际结果却表明反射方向的改变影响了实际采样的效果。

进一步调查表明,可能是反射方向的 z 值反转导致了异常的视觉效果,尽管预计这种反转不会导致如此明显的变化。在对相关的数学公式进行检查后,反射计算似乎并没有问题,但采样方向的变化仍然导致了问题。这个问题非常复杂,尚无法找到明确的解释,可能需要更多的调试工具来帮助分析。

总之,当前面临的主要问题是反射方向的变化导致了意外的曲率变化,尽管这个变化在理论上并不应该发生。

将采样向量绘制为RGB=XYZ*0.5+0.5,以便可视化

在调试过程中,使用了RGB采样向量来可视化采样方向。通过调整方向,采样向量被绘制为一种特定的模式,视觉效果呈现出从负一到一的变化,并被映射到零到一的范围。在这一过程中,碰到了一个问题,涉及到负值的y分量,并不理解为何负值会引起与正值不同的问题。

为了帮助分析,决定通过可视化z分量的采样方向,观察它的变化。接着进行了一些调试,检查在y分量接近零时,是否有特殊的表现,设定了特定的范围,以便找到相关问题的位置。通过进一步细化显示范围,发现当y分量接近零时,会出现一个不连续的现象,这也就是问题的所在。

在尝试分析负y值对结果的影响时,发现一些奇怪的行为发生在y值为负数时,尤其是在值接近零时。为了深入理解问题,选择绘制等值线图,观察特定范围内的变化,并进一步检查数值,确认问题是否出现在这些接近零的地方。通过逐步增加分辨率,发现问题似乎集中在接近0.5和0.7的值域内,显示出不连续性,但仍不清楚具体原因。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

地图是否在顶部或底部边缘被裁剪?(不确定这个问题是否合理。)

在调试过程中,提出了一个问题,是否映射在地图的顶部或底部边缘被裁剪。对于这个问题,虽然不确定是否发生了裁剪,但从观察到的地图的截面来看,似乎应该有足够的空间容纳相关数据。因此,怀疑这可能并不是裁剪的问题。

只有在使用顶部地图时才翻转BounceDirection.z

讨论了在地图绘制过程中如何处理与方向和采样有关的问题,特别是对于 z 分量的影响。问题分析如下:

  1. 变量翻转问题:通过翻转变量来修复问题看似可行,但没有清楚的原因解释。这种方式就像是不断增加负数直到问题消失,虽然暂时有效,但这种方法可能带来潜在的风险,因此需要深入分析问题的根本原因。

  2. y 值不受影响:观察到,尽管 z 方向的反弹会影响问题的表现,但 y 值似乎没有变化,这表明问题不在于 y 值的变化。

  3. 剪裁问题:尽管担心可能会发生剪裁,但通过断言检查后发现并未出现剪裁,说明在采样过程中,坐标值一直处于地图边界内,未发生意外的边界限制。

  4. 采样和反射:采样过程和反射计算看似无问题,未发现明显的错误,推测问题可能是由于采样方法或反射计算存在某些细微的问题,导致出现异常。

  5. 采样影响:当增加地图采样的范围时,异常现象变得不那么明显,甚至可能消失。通过进一步缩放 UV 坐标,可能会影响反射效果,尤其是在屏幕上的位置不同,会导致反射的拉伸效果。

  6. 参数调整:考虑增加新的参数来进一步探索问题,尝试通过更多的采样和参数控制来减少异常现象的影响。
    在这里插入图片描述

在这里插入图片描述

如果球体上下移动而不是左右移动,异常现象会如何变化?

异常如何随某些参数的变化而变化,重点分析了以下几点:

  1. 增加新参数:为了进一步分析问题,决定添加一个新参数,观察当系统上下移动时,异常是否发生变化。然而,逐渐产生了疑虑,认为这个方法可能不会对问题的解决有帮助,但还是决定尝试看看结果。

  2. y轴采样问题:出现了一个非常奇怪的现象,系统似乎没有正确地对y轴进行采样,但这种问题仅出现在某一张地图上,其他地方没有类似问题。这让问题变得异常复杂,导致难以找出原因。

  3. 困惑:虽然异常的现象清晰可见,但仍然无法理解问题的根本原因。感觉答案就在眼前,但暂时无法看清楚。相信当最终找到问题所在时,会是一个恍然大悟的时刻。
    在这里插入图片描述
    在这里插入图片描述

在纹理上显示采样?

讨论了如何将采样过程可视化,提出通过直接将采样结果写入纹理来观察采样的位置。这一方法的具体步骤如下:

  1. 直接写入纹理:决定将采样结果直接写入纹理,而不仅仅是使用线性插值采样。这可以帮助直观地看到正在采样的位置。

  2. 操作步骤:首先,禁用其他不必要的操作,然后在纹理中指定采样点的位置。具体做法是获取纹理指针,并通过LOD内存写入纹理数据。

  3. 反射问题:观察到反射效果很薄,这种情况是预期的。通过直接写入纹理,反射效果显示为非常细的区域,这是可以理解的,因为反射是从一个非常薄的区域进行采样的。

  4. 简化操作:通过不使用OpenGL等复杂框架,直接将采样结果绘制到纹理中,避免了繁琐的计算和理解步骤,使得处理过程变得更加直接和简洁。
    在这里插入图片描述

在这里插入图片描述

接下来的任务

  1. 反射问题:当前的主要任务是解决反射计算的问题。反射效果似乎不正确,可能是因为法线计算存在问题,或者是反射方向的计算出现了错误。怀疑是反射的计算过程有误,需要重新检查和确认。

  2. 下次计划:计划继续调试反射问题,确保法线转换正确,并且完成法线贴图的相关工作。接下来,可能会进入坐标系统的整理阶段,解决与坐标系相关的难题。