WebGL中的高级照明

时间:2015-06-30 14:00:58

标签: javascript webgl

我正在学习WebGL并在网上找到了一些有用的教程,这些教程帮助我获得了关于这个主题的一些基本知识,但是当事情变得非常有趣时,它们似乎都停止了。特别是在照明方面!

到目前为止,我了解如何使用Phong反射模型实现一些基本的局部照明,包括环境光,漫反射和镜面光照,或者使用定向或点光源,每个顶点或每个片段光照。

所以,这肯定是一件好事,但是因为这种方法非常有限,事实上,照明的质量对场景的真实性至关重要,我真的很想更进一步。

但这说起来容易做起来难!我一直在寻找教程或文章,描述如何在WebGL中实现更复杂的照明方法,但我找不到任何有用的东西!

就像站在厚厚的墙前,没有门,无法绕过! - 简直令人沮丧。

现在,因为我无法找到关于全局照明模型实现的WebGL相关信息或者如何使用光线跟踪和其他所有东西的描述,所以我们试图让场景看起来更逼真对一些人可以轻易找到的非常棒的WebGL作品做一些逆向工程。

但是由于事情的复杂性,以及由于缺乏富有洞察力的评论,甚至缺乏变量或功能的中间名称,以及原因,我自己技能的限制,我失败了!

然后,我试图进行更多的理论尝试,阅读有关数学基础知识的论文,但事实证明,它确实 很长一段时间 - 在大多数情况下解释不佳 - 数学没有编程上下文的公式,我的WebGL代码中的工作实现,所以,这样做就像我之前的努力一样无效......

嗯,我知道,在这个主板上要求提供有关这个主题的有用资源会被认为是不合适的(虽然我不知道,否则我可以在这里提出要求)并且我的帖子可能会被关闭,所以我&#39 ;我将添加一个更具体的问题:

当使用局部光照模型(例如,Phong反射模型)照亮对象时,我使用JavaScript创建几何体并将其与预先计算的法线一起传递给顶点着色器,然后我将位置的值与使用相关矩阵的正常数据并将结果传递给碎片整理器,其中每个像素的颜色使用照明模型提供的算法计算。

但是如果我想实现全局照明模型,它就不能以这种方式工作,可以吗?我的意思是,这需要将所有关于场景几何的信息转换为一个着色器,因此我必须调用gl.drawArrays( )或{{1只有一次并且所有我希望受到照明到一个缓冲区的影响,是吗?

这听起来既不像表演者也不像我的实际解决方案,所以肯定有更好的方法将它们结合起来,不是吗?现在,我如何解决在JavaScript中独立定义几何的问题,但是基于GLSL中整个场景的顶点数据计算全局光照?

我感谢任何帮助!最后,请原谅我糟糕的英语。

修改

PS:是的,我当然希望以更具体的方式提出问题,但具体实际上 是我面对这个问题的主要问题......; - )

尽管如此,关于如何在独立定义场景几何时如何计算全局光照的问题,我认识到,在我尝试分析的许多着色器源中,几何图形似乎完全是在片段着色器中创建的,只有一个从JavaScript传入的简单方块。

但基本上整个场景,片段着色器中定义的整个程序,只适用于极少数和简单的几何模型,我想。那么,如果我继续在JavaScript中定义几何体,那么在着色器之间交换信息需要什么(实际)选项才能实现一些全局照明算法?

1 个答案:

答案 0 :(得分:1)

在现实世界中,每一个表面都反射出来的光线的一部分,并吸收其它部分。实际上发光的物体很少,这就是准点光用于模拟那些发光物体(灯泡==点光源,方向==太阳等)。游戏通过仅使用那些准时光源来描述光照来近似照明效果并且假设计算仅对于某个光和网格对是局部的,这意味着,一个网格仅关注其附近的光源,并且实际上忽略了场景中的其他对象。为了解释一个对象实际影响另一个对象上的光照的效果,渲染引擎使用创建阴影或近似颜色出血的技术(全局照明)。

路径追踪使其正确:阴影,颜色流失,光照,焦散......这些都不是单独的现象,它们都是由光子在场景中反弹并与材料相互作用产生的。例如,环境遮挡和阴影效果相同:阴影越柔和细微,它们就会变成环境遮挡。颜色流失只是这样一种效应,即附近表面反射的光很多,反射光的表面可以被视为光源。因此,所有效果都是可以互换的,并且是光散射的结果。

游戏引擎无法在如此大规模和如此详细的情况下模拟所有这些行为,这就是为什么他们将照明分成某些非常有区别的效果。因此,他们在本地点亮对象,然后计算阴影,然后尝试找到颜色出血...然后他们独立计算相机效果,如绽放,运动模糊......所有这些效果和通行证被人为地分成不同的组,以便实时和根据他们携带的信息的数量和类型进行划分。

在实时渲染中完成的所有操作都是在本地执行操作的近似值,因为计算机没有足够的计算能力来模拟全局范围内的所有效果。欺骗这些限制的方法是预先计算事物,或者动态地执行它们,但要足够简单以使它们成为实时的。例如,对于颜色出血,我们可以预先计算整个场景中的光传输并通过使用大量的点光来近似它,每个点光对应于放置光的场景的特定体积的照明(这种技术称为虚拟点光)。

为了进行实时全局照明效果,并考虑到GPU的局限性,您需要对事物进行近似并简化它们。因此,您最终会使用VPL或体素锥形跟踪或屏幕空间光子贴图,或预滤波的局部立方体贴图,或任何其他可能满足您需求的技术。您表示仍然可以在本地访问和使用的时尚全局数据,这足以使整个场景足够接近。所以每个对象都不会对整个场景有所了解(好吧,这就是路径追踪的作用),但会给出一些代表全局照明的数据。

我希望这是有道理的并且有所帮助。

编辑后:

您无法在着色器之间交换数据。您可以尝试对场景进行体素化,然后将所获得的3D纹理传递给所有着色器。因此,所有着色器仍然彼此独立,但他们设法通过使用代表整个世界的相同数据来计算全局效果。