OGRE渲染引擎之光照、相机、阴影

2023-11-03 05:59

本文主要是介绍OGRE渲染引擎之光照、相机、阴影,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文翻译自OGRE 1.12.0

本教程将扩展在场景中使用Lights并使用它们投射阴影。

本教程的完整源代码(BasicTutorial2.cpp)可以在样本目录Samples / Tutorials中找到。

Note

有关如何设置Ogre项目并成功编译的说明,请参阅创建OGRE项目。

The OGRE Camera Class

相机是我们用来查看场景的对象。Ogre :: Camera是一个特殊的对象,其作用类似于Ogre :: SceneNode。它有类似setPosition和yaw这样的函数。你还可以将其附加到SceneNode。例如,你可能希望将摄像机临时附加到遵循天空路径的SceneNode以创建航空过场动画。就像SceneNode一样,Camera的位置将相对于其父SceneNode。Camera不是SceneNode(它实际上是从Frustum类继承的),但是对于移动和旋转,你可以将其视为SceneNode。

Note

从版本1.10开始,不推荐使用与旋转和平移相关的功能。你应该将相机附加到Ogre :: SceneNode并使用此节点进行所有转换。

Creating a Camera

我们现在将介绍我们刚刚在前一个教程中应用的相机创建部分。我们记得现在我们需要为像机创建SceneNode。第一步是创建SceneNode并要求SceneManager创建一个新的Camera。添加以下内容以创建SceneNode和Camera:

 SceneNode* camNode = scnMgr->getRootSceneNode()->createChildSceneNode();Camera* cam = scnMgr->createCamera("myCam");

您可以使用SceneManager的getCamera方法按名称检索相机。

接下来,我们将定位Camera并使用名为lookAt的方法使用camNode设置其方向。

camNode->setPosition(200, 300, 400);camNode->lookAt(Vector3(0, 0, 0), Node::TransformSpace::TS_WORLD);

Ogre :: SceneNode :: lookAt方法非常有用。它完全符合它的名字。它旋转SceneNode,使其视线聚焦在您给出的矢量上。使相机“看向”点。

我们要做的最后一件事(除了将摄像机连接到SceneNode之外)将近剪裁距离设置为5个单位。这是相机不再渲染任何网格的距离。如果你非常接近网格,这有时会切割网格,让你看到它的内部。另一种选择是用一块微小的,高度放大的网格纹理填充整个屏幕。这取决于你在场景中想要的东西。为了说明,我们将在此处进行设置。

cam->setNearClipDistance(5);camNode->attachObject(cam);

Viewports

在场景中处理多个摄像机时,Viewport的概念变得非常有用。我们现在将接触它,因为它将帮助您更多地了解Ogre如何决定在渲染场景时使用哪个相机。Ogre可以让多个SceneManagers同时运行。它还允许你分解屏幕并使用单独的相机渲染场景的不同视图。这将允许创建像分屏和迷你图这样的东西。这些内容将在后面的教程中介绍。

有三个结构对于理解Ogre如何渲染场景至关重要:Camera,SceneManager和RenderWindow。我们还没有介绍RenderWindow,它基本上代表了我们渲染的整个窗口。SceneManager将创建摄像机以查看场景,然后我们告诉RenderWindow在哪里显示每个摄像机的视图。我们告诉RenderWindow使用屏幕区域的方式是给它一个Ogre :: Viewport。在许多情况下,我们只需创建一个Camera并创建一个代表整个屏幕的Viewport。

Creating a Viewport

让我们为场景创建一个视口。为此,我们将使用RenderWindow的addViewport方法。

 Viewport* vp = getRenderWindow()->addViewport(cam);

getRenderWindow()是在OgreBites :: ApplicationContext中为我们定义的一个函数,它返回Ogre :: RenderWindow。

现在让我们设置视口的背景颜色。

 vp->setBackgroundColour(ColourValue(0, 0, 0));

我们将它设置为黑色,因为我们稍后会添加彩色照明,我们不希望背景颜色影响我们看到照明的方式。

我们要做的最后一件事是设置相机的纵横比。如果您使用的是标准全窗口视口以外的其他内容,则无法设置此项可能会导致场景失真。我们将在此处设置它以进行演示,即使我们使用的是默认宽高比。

cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

 我们从视口中检索宽度和高度以设置纵横比。

正如我们所提到的,默认设置已经设置为使用全屏的尺寸。

编译并运行您的应用程序。你应该只看到黑屏,只要确保它运行。

Building the Scene

在我们进入阴影和光照之前,让我们在场景中添加一些元素。让我们把一个忍者放在事物的中间。设置环境光后立即添加以下代码:

 Entity* ninjaEntity = scnMgr->createEntity("ninja.mesh");ninjaEntity->setCastShadows(true);scnMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ninjaEntity);

这应该看起来很熟悉,除非我们要求网格这次投射阴影。请注意,这次我们创建了一个子场景节点,并将ninjaEntity全部连接在一起。

我们还将为忍者创造一些东西。我们可以使用Ogre :: MeshManager从头开始创建网格。我们将使用它来生成纹理平面以用作地面。

我们要做的第一件事是创建一个抽象的Plane对象。这不是网格,它更像是一个蓝图。

 Plane plane(Vector3::UNIT_Y, 0);

我们通过提供一个垂直于我们的平面的矢量和它到原点的距离来创建一个平面。所以我们创建了一个垂直于y轴的平面并且距离原点的零个单位。如下图:

 Plane构造函数还有其他重载,使得我们传递第二个向量而不是距离原点的距离。这允许我们在想要的3D空间中构建任何平面。

现在我们要求MeshManager使用我们的平面蓝图创建一个网格。MeshManager已经在初始化我们的应用程序时跟踪我们加载的资源。最重要的是,它可以为我们创建新的网格。

MeshManager::getSingleton().createPlane("ground", RGN_DEFAULT,plane,1500, 1500, 20, 20,true,1, 5, 5,Vector3::UNIT_Z);

这是一个复杂的函数,我们还没有完全了解它。如果您想了解更多信息,可以阅读Ogre :: MeshManager类规范。基本上,我们创建了一个名为“ground”的新网格,大小为1500x1500。

现在我们将使用这个网格创建一个新实体。

   Entity* groundEntity = scnMgr->createEntity("ground");scnMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);

请注意,不要把为createEntity指定的参数混淆为Entity的名称。它实际上是我们刚刚创建的网格的名称。我们习惯于看到网格名称以'.mesh'结尾。

我们想告诉SceneManager不要从我们的地面实体投射阴影。这其实只是一种浪费。不要混淆,这意味着地面不会投下阴影,这并不意味着我们不能将阴影投射到地面上。

groundEntity->setCastShadows(false);

最后,我们需要提供一个材质。目前,最简单的方法是使用Ogre包含的脚本中的材质及其样本。您应该在SDK或您下载的源目录中使用这些资源来构建Ogre。

 groundEntity->setMaterialName("Examples/Rockwall");

确保将材质和Examples.material脚本的纹理添加到资源加载路径。在我们的例子中,纹理名称为'rockwall.tga'。您可以通过阅读材料脚本中的条目自己找到该名称。

Using Shadow in Ogre

在Ogre中启用阴影很容易。SceneManager类有一个我们可以使用的Ogre :: SceneManager :: setShadowTechnique方法。然后每当我们创建一个实体时,我们调用setCastShadows来选择将投射阴影的实体。setShadowTechinique方法采用了几种不同的技术。有关更多详细信息,请参阅Ogre :: ShadowTechnique。

让我们关掉环境光,这样我们就能看到灯光的全部效果。添加以下内容:

 scnMgr->setAmbientLight(ColourValue(0, 0, 0));scnMgr->setShadowTechnique(ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE);

现在SceneManager将使用调制模板阴影。让我们添加一些灯来看这个动作

Lights

Ogre提供三种类型的光照。

  • Ogre :: Light :: LT_POINT  - 此光从一个点向各个方向均匀地发散。
  • Ogre :: Light :: LT_SPOTLIGHT  - 这个灯像手电筒一样工作。 它产生一个光柱,在中心更亮,并逐渐消失。
  • Ogre::Light::DIRECTIONAL- 这个光模拟了一个非常遥远的巨大光源 - 就像日光一样。 光线以相同的角度到达整个场景。
  • Ogre :: Light类具有广泛的属性。其中最重要的两个是漫反射和镜面反射颜色。每个材质脚本定义材质反射的镜面和漫反射光照量。这些属性将在后面的一些教程中介绍。

Creatint a Light

让我们为场景添加一个灯光。我们通过调用Ogre :: SceneManager :: createLight函数来完成此操作。创建完groundEntity后立即添加以下代码:

  Light* spotLight = scnMgr->createLight("SpotLight");

我们将漫反射和镜面反射颜色设置为纯蓝色。

 spotLight->setDiffuseColour(0, 0, 1.0);spotLight->setSpecularColour(0, 0, 1.0);

 接下来,我们将灯光的类型设置为聚光灯。

spotLight->setType(Light::LT_SPOTLIGHT);

聚光灯需要一个位置和一个方向 - 记住它就像一个手电筒。我们将聚光灯放在忍者的右肩上方,以45度的角度照射在他身上。

 SceneNode* spotLightNode = scnMgr->getRootSceneNode()->createChildSceneNode();spotLightNode->attachObject(spotLight);spotLightNode->setDirection(-1, -1, 0);spotLightNode->setPosition(Vector3(200, 200, 0));

 

最后,我们设置了所谓的聚光灯范围。这些角度决定了光从中间的明亮区域到外侧边缘的调光器的位置。

 spotLight->setSpotlightRange(Degree(35), Degree(50));

编译并运行应用程序。你应该看到一个忍者的阴影蓝色图。

 Creating More Lights

接下来,我们将为场景添加定向光。这种类型的光基本上模拟日光或月光。灯光在整个场景中以相同的角度投射。和以前一样,我们首先创建Light并设置其类型。

 Light* directionalLight = scnMgr->createLight("DirectionalLight");directionalLight->setType(Light::LT_DIRECTIONAL);

现在我们将漫反射和镜面反射颜色设置为深红色。

 directionalLight->setDiffuseColour(ColourValue(0.4, 0, 0));directionalLight->setSpecularColour(ColourValue(0.4, 0, 0));

最后,我们需要设置Light的方向。定向光没有位置,因为它被建模为无限远的点光源。

SceneNode* directionalLightNode = scnMgr->getRootSceneNode()->createChildSceneNode(); directionalLightNode->attachObject(directionalLight);
directionalLightNode->setDirection(Vector3(0, -1, 1));

 Light类还定义了一个Ogre :: Light :: setAttenuation函数,它允许你控制光线离开更远时的消散方式。完成本教程后,请尝试在场景中使用此函数以查看它对灯光的影响。

编译并运行应用程序。你的忍者现在应该在他身后投下阴影,场景应该充满红光。

 为了完成该设置,我们现在将为我们的场景添加一个点光源。

Light* pointLight = scnMgr->createLight("PointLight");
pointLight->setType(Light::LT_POINT);

我们将镜面反射和漫反射颜色设置为深灰色。

 pointLight->setDiffuseColour(0.3, 0.3, 0.3);pointLight->setSpecularColour(0.3, 0.3, 0.3);

点光源没有方向,它只有一个位置。我们将最后一盏灯放在忍者的上方和后方。

  SceneNode* pointLightNode = scnMgr->getRootSceneNode()->createChildSceneNode();pointLightNode->attachObject(pointLight);pointLightNode->setPosition(Vector3(0, 150, 250));

编译并运行应用程序。你现在应该在忍者面前看到一个长长的阴影。你应该看到点光源的效果使忍者背后的区域变亮。试着想一想为什么颜色会像他们那样。例如,为什么忍者背后的阴影似乎根本没有红色?

Shadow Types

 Ogre支持一组不同的阴影类型。更多有关详细信息,请参阅Ogre :: ShadowTechnique枚举器。

尝试尝试不同的阴影类型。您可以在Ogre :: SceneManager类中使用其他与阴影相关的方法。

Ogre不提供软阴影作为引擎的一部分。您可以编写自己的顶点和片段程序来实现软阴影和许多其他内容。ogre手册有阴影的完整描述。

Conclusion

本教程介绍了如何在场景中使用灯光和阴影。首先,我们介绍了如何使用MeshManager从头开始生成网格。然后我们选择了Ogre应该使用哪种阴影类型。最后,我们开始向场景添加每种类型Light的示例。我们创造了聚光灯,定向灯和点光源。你甚至可以通过编写自己的顶点和片段程序来扩展Ogre的光照和阴影系统。有关详细信息,请参阅ogre手册。

我们已经介绍了许多不同的设置,允许你自定义Ogre渲染光影的方式。完成每个教程后,最好使用你拥有的新工具。这将大大提高您使用库的舒适度,这是学习使用API文档的绝佳方式。

这篇关于OGRE渲染引擎之光照、相机、阴影的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/336073

相关文章

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

UE5 半透明阴影 快速解决方案

Step 1: 打开该选项 Step 2: 将半透明材质给到模型后,设置光照的Shadow Resolution Scale,越大,阴影的效果越好

Smarty模板引擎工作机制(一)

深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。 在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码: <?php$title="深处浅出之Smarty模板引擎工作机制";$content=

海鸥相机存储卡格式化如何恢复数据

在摄影的世界里,‌每一张照片都承载着独特的记忆与故事。‌然而,‌当我们不慎将海鸥相机的存储卡格式化后,‌那些珍贵的瞬间似乎瞬间消逝,‌让人心急如焚。‌但请不要绝望,‌数据恢复并非遥不可及。‌本文将详细介绍在海鸥相机存储卡格式化后,‌如何高效地恢复丢失的数据,‌帮助您重新找回那些宝贵的记忆。‌ 图片来源于网络,如有侵权请告知 一、‌回忆备份情况 ‌海鸥相机存储卡格式化如何恢复数据?在意

MySQL技术内幕_innodb存储引擎

MySQL技术内幕_innodb存储引擎 INNODB innodb中如果表没有主键 表是否由 非空唯一键,有则该字段为主键没有,则自动创建一个6字节大小的指针 innodb存储引擎的所有数据都存储在表空间中,表空间由段,区,页(块)组成。 如果启用了 innodb_file_per_table, 则每张表内的数据可以单独放在一个表空间中即使启用了上面参数,共享表空间也会因为 系统事务信息