博客
关于我
OSG学习:纹理映射(六)——灯光
阅读量:794 次
发布时间:2023-02-26

本文共 3318 字,大约阅读时间需要 11 分钟。

在OpenSceneGraph中添加光源是一个关键步骤,正确配置光源可以显著提升场景的渲染效果。本文将详细介绍如何在OpenSceneGraph场景中添加并配置光源。

添加光源的步骤

在OpenSceneGraph中添加光源的主要步骤如下:

1. 准备渲染状态

在渲染状态中需要开启光照并允许光源,这样才能正确显示光照效果。具体操作如下:

  • 设置渲染状态为启用光照:stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
  • 允许使用一个光源:stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);

2. 创建光源对象

光源在OpenSceneGraph中通过osg::Lightosg::LightSource类来实现。具体步骤如下:

  • 创建osg::Light对象并设置其属性:
    osg::ref_ptr
    light = new osg::Light();
    light->setLightNum(0);
    light->setDirection(osg::Vec3(0.0f, 0.0f, -1.0f));
    light->setPosition(osg::Vec4(bs.center().x(), bs.center().y(), bs.center().z() + bs.radius(), 1.0f));
    light->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    light->setConstantAttenuation(1.0f);
    light->setLinearAttenuation(0.0f);
    light->setQuadraticAttenuation(0.0f);
  • 创建osg::LightSource对象并将其与osg::Light绑定:
    osg::ref_ptr
    lightSource = new osg::LightSource();
    lightSource->setLight(light.get());

3. 将光源节点添加到场景中

创建光源节点后,将其添加到场景图形中,以便渲染时能够正确显示光照效果。具体实现如下:

osg::ref_ptr
lightRoot = new osg::Group();
stateset = lightRoot->getOrCreateStateSet();
lightRoot->addChild(node);
lightRoot->addChild(lightSource.get());

注意事项

在配置光源时,需要注意以下几点:

  • 单位法线:确保场景模型的法线为单位长度,否则光照效果可能会异常。
  • 光源位置:光源的位置和方向需要根据具体场景需求进行调整,建议参考场景的几何结构。

代码示例

以下是完整的代码示例,展示了在OpenSceneGraph中创建并添加光源的过程:

#include 
#include
#include
#include
#include
using namespace std;
osg::ref_ptr
createLight(osg::ref_ptr
node) {
osg::ref_ptr
lightRoot = new osg::Group();
osg::StateSet* stateset = lightRoot->getOrCreateStateSet();
// 设置光照状态
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);
// 计算包围盒
osg::BoundingSphere bs;
node->computeBound();
bs = node->getBound();
// 创建光源
osg::ref_ptr
light = new osg::Light();
light->setLightNum(0);
light->setDirection(osg::Vec3(0.0f, 0.0f, -1.0f));
light->setPosition(osg::Vec4(bs.center().x(), bs.center().y(), bs.center().z() + bs.radius(), 1.0f));
light->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
light->setConstantAttenuation(1.0f);
light->setLinearAttenuation(0.0f);
light->setQuadraticAttenuation(0.0f);
// 创建光源节点
osg::ref_ptr
lightSource = new osg::LightSource();
lightSource->setLight(light.get());
// 将光源节点添加到场景中
lightRoot->addChild(node);
lightRoot->addChild(lightSource.get());
return lightRoot.get();
}
int main() {
// 读取场景文件
osg::ref_ptr
node = osgDB::readNodeFile("cow.osg");
osg::ref_ptr
root = new osg::Group();
root->addChild(createLight(node.get()));
// 优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
// 初始化视图
osg::ref_ptr
viewer = new osgViewer::Viewer();
viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
viewer->setSceneData(root.get());
viewer->realize();
// 运行视图
return viewer->run();
}

结果展示

通过上述配置,光源将正确添加到场景中,并根据配置显示相应的光照效果。按以下键可以查看不同的光照效果:

  • l:切换到光照模式
  • L:切换到非光照模式
  • b:切换背面剔除模式
  • t:切换纹理状态

通过上述步骤和代码示例,开发者可以轻松在OpenSceneGraph中添加并配置光源,充分发挥三维渲染的效果。

转载地址:http://juvfk.baihongyu.com/

你可能感兴趣的文章
OSG学习:场景图形管理(二)——单窗口多相机渲染
查看>>
OSG学习:场景图形管理(四)——多视图多窗口渲染
查看>>
OSG学习:新建C++/CLI工程并读取模型(C++/CLI)——根据OSG官方示例代码初步理解其方法
查看>>
Sql 随机更新一条数据返回更新数据的ID编号
查看>>
OSG学习:空间变换节点和开关节点示例
查看>>
OSG学习:纹理映射(一)——多重纹理映射
查看>>
OSG学习:纹理映射(七)——聚光灯
查看>>
OSG学习:纹理映射(三)——立方图纹理映射
查看>>
OSG学习:纹理映射(二)——一维/二维/简单立方图纹理映射
查看>>
OSG学习:纹理映射(五)——计算纹理坐标
查看>>
OSG学习:纹理映射(六)——灯光
查看>>