关于算法:Chai-3D之灯光与阴影

9次阅读

共计 4564 个字符,预计需要花费 12 分钟才能阅读完成。

举荐:将 NSDT 场景编辑器 退出你的 3D 开发工具链

介绍

  光是人类能够视觉感知的任何事物的视觉示意背地的最重要的思维。光感知的概念在于,你所看到的不是基于你正在观看的物体,而是基于光源投射并从这些物体反射的光线。重要的是要留神,你的眼睛不会间接看到物体,因为你的眼睛和这些物体之间没有物理相关性。
  当然,所有这些都是实践上的。咱们应用术语光线只是形象出更简单的机制。
  光线通常来自能量起源,例如太阳或房间内的灯。重要的是要留神,从实践上讲,光线沿直线传播,当您在视觉上感知物体时,您的眼睛排汇的是该物体反射或散射的光线。

光的形象类型

  以下术语形容了在对须要光源的 3D 应用程序进行编程时必须理解的不同类型的光。理解每种类型的光在渲染的 3D 对象外表上产生的成果十分重要。创立这些术语是因为须要形容光对物体产生的某些成果,以便提炼出光的简单数学计算。然而,这并不意味着这些确切类型的光实际上存在于自然界中,咱们只是将它们视为光投射在不同资料上时可能产生的成果的形象。计算光的实在机制及其在自然界中的工作形式将十分耗时,因而,OpenGL 通常采纳这组常见的光类型:环境光、漫射光和镜面光。发射光与其余光不同,是物体收回的光的类型,而其余三种类型的光通常用于形容光源。让咱们具体看看这些类型的光:

将环境、漫反射和镜面反射重量组合在一起

环境光

  被环境光照亮的 3D 球体看起来只有 2D。环境光是由照明区域四周(或位于照明区域外部)的所有光源发射光而产生的均匀光量。当阳光穿过房间的窗户时,它们会打到墙壁上,反射并散射到各个不同的方向,均匀照亮整个房间。这种视觉品质由环境光形容。仅环境光无奈传播在 3D 空间中设置的对象的残缺示意,因为所有顶点都由雷同的色彩平均照明,并且对象看起来像是二维的,如上图所示。只管显示的对象实际上是一个 3D 球体,但当仅由环境光照亮时,它在屏幕上看起来是平坦的。

漫反射光

  红色的漫射光投射到定义其 3D 形态的彩色物体上。
  漫射光示意光源投射的定向光。漫射光能够形容为在空间中具备地位并且来自单个方向的光。手电筒略微高于它所照亮的物体,能够被认为是发射漫射光。在上图中,投射红色漫射光的光源位于物体的左侧。当漫射光接触物体外表时,它会在该外表上平均地散射和反射。
  为了演示环境光和漫射光如何协同工作以创立看起来更真切的对象,请设想一个 3D 球体,其上分布着深红色的环境光:
  当初,通过将漫射光源搁置在球体的右侧,咱们失去以下后果:
  请留神球体当初看起来是 3D 的。

镜面光

  除了环境光层和漫反射层外,此处还显示镜面反射(或镜面反射高光)。您能够察看到镜面反射光源属性如何大大加强对象的 3D 示意。就像漫射光一样,镜面反射光是一种定向光。它来自一个特定的方向。
  两者之间的区别在于镜面光以锐利而平均的形式从外表反射。镜面反射光的渲染取决于观察者和光源之间的角度。从观察者的角度来看,镜面反射光会在被察看对象的外表上创立一个突出显示的区域,称为镜面反射或镜面反射。镜面反射的强度取决于形成物体的资料以及蕴含镜面反射光重量的光源的强度。

发射光

  自发光与之前解释的任何其余光重量略有不同。自发光光组件负责物体材质反射或排汇光的属性。当利用于对象的材质时,自发光光的作用是模仿从物体反射的光。
  因为四周没有其余光源,仅利用自发光光重量的物体色彩与仅应用环境光的对象具备雷同的视觉品质。然而,任何额定的漫射光或镜面光如何与仅施加自发光光的同一物体的表面反应的机制是不同的。让咱们思考一个均匀收回绿色的物体。在下图中,自发光重量利用于球体。如您所见,后果相似于在下面示例中将环境光利用于同一球体所创立的成果。
  反射绿色自发光光的 3D 球体。在将其余光源引入场景之前,该成果相似于环境光。如您所知,光源能够调配所有三个组件,即环境光、漫反射光和镜面反射光组件。让咱们看看当咱们在下面的场景中利用光源时会产生什么。咱们利用的光源具备以下属性:红色环境光、红色漫射光和红色镜面光。
  如果下面的球体没有收回绿色的光,它就会出现红色。然而,自发光的绿色重量被施加到它下面。当光源的“光线”照射到球体外表时,“光源”和“指标”色彩交融在一起,产生淡黄色的外表。光源的镜面反射光重量为红色。镜面反射的核心核心是红色的,然而当它扩散时,它与绿色和红色交融,在黄色(即绿红色)上减少。同样,请留神,如果没有将自发光光利用于球体,它看起来就像下面镜面反射局部下显示的球体一样,全副为红色,带有红色镜面反射。
  本教程的以下局部将介绍 OpenGL 着色多边形以模仿光线的形式,以及如何将光源属性调配给光源和材质。

光源

  为了计算 3D 物体的暗影,CHAI3D 须要晓得落在其上的光线的强度、方向和色彩。这些属性由世界中的光对象提供。所有光源的基色和强度设置雷同,但方向取决于您应用的光源类型。此外,光线可能会随着与光源的间隔而削弱。上面介绍了 CHAI3D 中可用的三种类型的光源。

CHAI3D 光源

位置灯

  地位光位于空间中的某个点,并平等地向各个方向收回光。光线照耀外表的方向是从接触点回到光对象核心的线。强度随着与光的间隔而减小,在指定范畴内达到零。点光源可用于模仿场景中的灯和其余部分光源。

using namespace chai3d;
// create a light source
light = new cPositionalLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(1.0, 1.0, 0.5);

方向灯

  定向光源没有任何可辨认的光源地位,因而光源对象能够搁置在世界任何中央。世界上所有的物体都被照亮,就如同光线总是来自同一个方向一样。光与指标物体的间隔未定义,因而光不会削弱。
  定向光源示意来自流动工作区范畴之外的地位的大而远的光源。在真切的场景中,它们能够用来模仿太阳或月亮。在形象的模仿世界中,它们能够成为一种有用的办法,能够为对象增加令人信服的暗影,而无需精确指定光线的起源。在场景视图中查看对象时(例如,查看其网格、着色器和材质的外观),定向光通常是理解其着色显示方式的最快办法。对于这样的测试,您通常对光线来自哪里不感兴趣,而只是想看到物体看起来“固体”并寻找模型中的毛刺。

using namespace chai3d;
// create a directional light source
light = new cDirectionalLight(world);
// insert light source inside world
world->addChild(light);
// enable light source
light->setEnabled(true);
// define direction of light beam
light->setDir(-1.0, 0.0, 0.0);

聚光灯

  与地位光源一样,聚光灯具备光源落落的指定地位和范畴。然而,聚光灯被限度在一个角度,导致锥形照明区域。圆锥体的核心指向光源对象的向后(X)方向。
  聚光灯通常用于人造光源,例如能够连贯到触觉工具(例如模仿内窥镜)的手电筒。

using namespace chai3d;
// create a light source
light = new cSpotLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(0.6, 0.6, 0.5);
// define the direction of the light beam
light->setDir(-0.5,-0.5,-0.5);

暗影

灯光与暗影
  暗影映射或投影暗影是将暗影增加到 3D 计算机图形的过程。暗影是通过测试像素从光源中是否可见来创立的,办法是将其与以纹理模式存储的光源视图的 z 缓冲区或深度图像进行比拟。

从光源生成的暗影贴图

  如果你从光源向外看,你能看到的所有物体都会呈现在光线中。然而,这些物体前面的任何货色都会在暗影中。这是用于创立暗影贴图的根本准则。渲染光源的视图,存储它看到的每个外表的深度(暗影贴图)。接下来,渲染惯例场景,将绘制的每个点的深度(如同它被光而不是眼睛看到)与此深度图进行比拟。

示例

  在 CHAI3D 中,聚光灯反对暗影贴图。在上面的示例中,咱们阐明了如何设置暗影贴图。

using namespace chai3d;
// create a light source
light = new cSpotLight(world);
// attach light to camera
world->addChild(light);
// enable light source
light->setEnabled(true);
// position the light source
light->setLocalPos(0.6, 0.6, 0.5);
// define the direction of the light beam
light->setDir(-0.5,-0.5,-0.5);
// set light cone half angle
light->setCutOffAngleDeg(30);
// enable this light source to generate shadows
light->setShadowMapEnabled(true);

  为了最大限度地进步暗影的品质,重要的是 de 调配尽可能小的截止角度。此外,能够通过进步暗影贴图的分辨率来调整暗影贴图的品质。较大的暗影贴图显然须要更长的工夫来渲染,并且在低性能图形卡上可能不受反对。

using namespace chai3d;
// (1) set the resolution of the shadow map - low quality
light->m_shadowMap->setQualityLow();
// (2) set the resolution of the shadow map - medium quality
light->m_shadowMap->setQualityMedium();
// (3) set the resolution of the shadow map - high quality
light->m_shadowMap->setQualityHigh();

  渲染摄像机场景时,首先更新所有暗影贴图十分重要。如果应用多个摄像机和多个帧缓冲区(窗口显示)渲染场景,则只需计算一次暗影贴图。

using namespace chai3d;
// update shadow maps
world->updateShadowMaps(false, mirroredDisplay);
// render scene
camera->renderView(windowW, windowH);

3D 建模学习工作室翻译整顿,转载请表明出处!

正文完
 0