Math 改进WebGL中的区域照明&;三个

Math 改进WebGL中的区域照明&;三个,math,3d,three.js,webgl,lighting,Math,3d,Three.js,Webgl,Lighting,我一直致力于WebGL中的区域照明实现,类似于此演示: 上述three.js中的实现是从gamedev.net上ArKano22的工作移植而来的: 尽管这些解决方案令人印象深刻,但它们都有一些局限性。ArKano22最初实现的主要问题是漫反射项的计算不考虑曲面法线 几个星期以来,我一直在扩充这个解决方案,并和redPlant一起改进以解决这个问题。目前,我有正常的计算纳入解决方案,但结果也有缺陷 以下是我当前实现的预览: 介绍 计算每个片段的漫反射项的步骤如下: 将顶点投影到区域灯光所在的

我一直致力于WebGL中的区域照明实现,类似于此演示:

上述three.js中的实现是从gamedev.net上ArKano22的工作移植而来的:

尽管这些解决方案令人印象深刻,但它们都有一些局限性。ArKano22最初实现的主要问题是漫反射项的计算不考虑曲面法线

几个星期以来,我一直在扩充这个解决方案,并和redPlant一起改进以解决这个问题。目前,我有正常的计算纳入解决方案,但结果也有缺陷

以下是我当前实现的预览:

介绍 计算每个片段的漫反射项的步骤如下:

  • 将顶点投影到区域灯光所在的平面上,以便投影向量与灯光的法线/方向重合
  • 通过比较投影向量和灯光法线,检查顶点是否位于区域灯光平面的正确一侧
  • 计算平面上该投影点相对于灯光中心/位置的二维偏移
  • 钳制此二维偏移向量,使其位于灯光区域内(由其宽度和高度定义)
  • 导出投影和固定的二维点的三维世界位置。这是区域灯光上距离顶点最近的点
  • 通过获取顶点到最近点向量(归一化)和顶点法线之间的点积,执行点光源的常规漫反射计算
  • 问题 此解决方案的问题是,照明计算是从最近的点进行的,而不考虑灯光表面上可能会照亮碎片的其他点。让我试着解释一下为什么

    考虑下图:

    区域光既垂直于曲面,又与曲面相交。曲面上的每个碎片将始终返回曲面和灯光相交的区域灯光上最近的点。由于曲面法线和顶点到光向量始终垂直,因此它们之间的点积为零。随后,漫反射贡献的计算为零,尽管表面上隐现着大面积的光

    势解 我建议不要从区域光上最近的点计算光,而是从区域光上的点计算光,该点在顶点到光向量(归一化)和顶点法线之间产生最大的点积。在上图中,这将是紫色点,而不是蓝色点

    救命啊! 所以,这就是我需要你帮助的地方。在我的头脑中,我很清楚这一点是如何推导出来的,但我没有数学能力得出答案

    目前,我的片段着色器中有以下可用信息:

    • 顶点位置
    • 顶点法线(单位向量)
    • 灯光位置、宽度和高度
    • 光法线(单位矢量)
    • 灯光右侧(单位矢量)
    • 亮起(单位矢量)
    • 从顶点到灯光平面的投影点(3D)
    • 从灯光中心的投影点偏移(2D)
    • 夹紧偏移(2D)
    • 此夹紧偏移的世界位置–最近点(3D)
    为了将所有这些信息放到一个可视上下文中,我创建了这个图表(希望有帮助):

    为了测试我的建议,我需要区域光上的投射点,用红点表示,这样我可以在顶点到投射点(归一化)和顶点法线之间执行点积。同样,这应该产生最大可能的贡献值

    更新!!! 我已经在CodePen上创建了一个交互式草图,该草图将我目前实现的数学可视化:

    您应该关注的相关代码是第318行

    castingPoint.location
    THREE.Vector3
    的一个实例,是拼图中缺失的一块。您还应该注意到,草图左下方有两个值–这些值会动态更新,以显示相关向量之间的点积


    我想这个解决方案需要另一个伪平面,它与顶点法线的方向对齐,并且垂直于灯光的平面,但我可能错了

    我们一致认为施法点总是在边缘

    假设“照明部分”是空间的一部分,由沿法线拉伸的灯光四边形表示

    如果曲面点位于照亮的部分,则需要计算保持该点的平面,它是法向量和灯光的法线。该平面和灯光之间的交点将为您提供两个点作为选项(仅两个,因为投射点始终位于边上)。因此,测试这两个,看看哪一个贡献更大

    如果该点不在照明部分中,则可以计算四个平面,每个平面都有曲面点、其法线和灯光四边形的一个顶点。对于每个灯光四边形顶点,您将有两个点(顶点+另一个交点)来测试哪一个贡献最大

    这应该能奏效。如果您遇到任何反例,请给我反馈。

    如果我理解正确:

    定义L“点x0的灯光”

    L~K/S^2

    S=sqrt(y^2+x0^2)

    L=和(k/(sqrt(y^2+x0^2))^2,y=0..无穷大

    L=和(k/(y^2+x0^2)),y=0..无穷大,x>0,y>0

    L=积分(k/(y^2+x0^2)),y=0..infinity=k*Pi/(2*x0)

    答复:

    L=k*Pi/(2)*