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

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

在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/

你可能感兴趣的文章
oracle 创建字段自增长——两种实现方式汇总
查看>>
Oracle 升级10.2.0.5.4 OPatch 报错Patch 12419392 Optional component(s) missing 解决方法
查看>>
Oracle 递归
查看>>
oracle--用户,权限,角色的管理
查看>>
Oracle10g EM乱码之快速解决
查看>>
Oracle11G基本操作
查看>>
Oracle11g服务详细介绍及哪些服务是必须开启的?
查看>>
Oracle11g静默安装dbca,netca报错处理--直接跟换操作系统
查看>>
oracle12安装软件后安装数据库,然后需要自己配置监听
查看>>
Oracle——08PL/SQL简介,基本程序结构和语句
查看>>
Oracle——distinct的用法
查看>>
oracle下的OVER(PARTITION BY)函数介绍
查看>>
Oracle中DATE数据相减问题
查看>>
Oracle中merge into的使用
查看>>
oracle中sql查询上月、本月、上周、本周、昨天、今天的数据!
查看>>
oracle中sql的case语句运用--根据不同条件去排序!
查看>>
oracle中关于日期问题的汇总!
查看>>
Oracle中常用的语句
查看>>
Oracle中的rownum 和rowid的用法和区别
查看>>
oracle中的大小写、字符、dual、数字、处理、日期、函数、显/隐式、时间、条件表达式case、decode、to_date、to_char、sysdate
查看>>