查看: 4569|回复: 4

透明贴图和阴影问题

[复制链接]

该用户从未签到

发表于 2012-11-27 10:26:34 | 显示全部楼层 |阅读模式
有两张背景是透明的png图片都是512*512
2.png 1.png
将他们分别当做纹理贴在一个正方形节点上,设置属性使节点变成透明,再加入飞机模型cessna.osg
利用阴影示例的代码开启影子
但是结果不是我们想要的
捕获2副本.png 捕获副本.png
我们发现影子不在花上的都不能显示,其实想要完成的功能是在一个透明材质上的模型显示出影子 不知道有没有解决方法
代码如下:
  1. /**********************************************************
  2. *Write by FlySky
  3. *zzuxp@163.com  http://www.OsgChina.org   
  4. **********************************************************/

  5. #include <osgViewer/Viewer>

  6. #include <osg/Node>
  7. #include <osg/Geode>
  8. #include <osg/Group>
  9. #include <osg/Camera>
  10. #include <osg/ShapeDrawable>
  11. #include <osg/ComputeBoundsVisitor>
  12. #include <osg/BoundingBox>
  13. #include <osg/BoundingSphere>
  14. #include <osg/AnimationPath>

  15. #include <osgDB/ReadFile>
  16. #include <osgDB/WriteFile>

  17. #include <osgShadow/ShadowedScene>
  18. #include <osgShadow/ShadowVolume>
  19. #include <osgShadow/ShadowTexture>
  20. #include <osgShadow/ShadowMap>
  21. #include <osgShadow/SoftShadowMap>
  22. #include <osgShadow/ParallelSplitShadowMap>
  23. #include <osgUtil/Optimizer>
  24. #include <iostream>
  25. #include "Tex.h"

  26. //标识阴影接收对象
  27. const int ReceivesShadowTraversalMask = 0x1;
  28. //标识阴影投影对象
  29. const int CastsShadowTraversalMask = 0x2;

  30. //创建地形平面
  31. osg::ref_ptr<osg::Node> CreateShadowReceiverNode()
  32. {
  33.         osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  34.         //设置纹理属性
  35.         osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();        osg::ref_ptr<osg::Image> image = osgDB::readImageFile("2.png");
  36.         if (image.get())
  37.         {
  38.                 osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
  39.                 //texture->setDataVariance(osg::Object::DYNAMIC);
  40.                 texture->setImage(image.get());
  41.                 stateset->setTextureAttributeAndModes(0,texture.get(),osg::StateAttribute::ON);


  42.                 // 启用混合,设置透明.
  43.                 stateset->setMode( GL_BLEND, osg::StateAttribute::ON );
  44.                 stateset->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

  45.         }

  46.         osg::Geometry* geom = new osg::Geometry;
  47.         osg::Vec3Array* vertices = new osg::Vec3Array;
  48.         vertices->push_back(osg::Vec3(-256,255,-15.1));
  49.         vertices->push_back(osg::Vec3(-256,-256,-15.1));
  50.         vertices->push_back(osg::Vec3(255,-256,-15.1));
  51.         vertices->push_back(osg::Vec3(255,255,-15.1));
  52.         geom->setVertexArray(vertices);

  53.         osg::Vec3Array* normals = new osg::Vec3Array;
  54.         normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
  55.         geom->setNormalArray(normals);
  56.         geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

  57.         osg::ref_ptr<osg::Vec2Array>vt=new osg::Vec2Array();
  58.         vt->push_back(osg::Vec2(0.0f,0.0f));
  59.         vt->push_back(osg::Vec2(1.0f,0.0f));
  60.         vt->push_back(osg::Vec2(1.0f,1.0f));
  61.         vt->push_back(osg::Vec2(0.0f,1.0f));

  62.         geom->setTexCoordArray(0,vt.get());

  63.         geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
  64.         geode->addDrawable(geom);
  65.     geode->setStateSet(stateset.get());


  66.         osg::ref_ptr<osg::Group> group = new osg::Group;
  67.         group->addChild(geode.get());

  68.         return group.get();
  69. }


  70. //创建一个光照
  71. osg::ref_ptr<osg::Node> CreateLight(osg::ref_ptr<osg::Node> model)
  72. {
  73.         osg::ComputeBoundsVisitor cbbv;
  74.         model->accept(cbbv);
  75.         osg::BoundingBox bb = cbbv.getBoundingBox();

  76.         osg::Vec4 lightpos;

  77.         lightpos.set(bb.center().x(), bb.center().y(), bb.zMax() + bb.radius()*2.0f  ,1.0f);

  78.         osg::ref_ptr<osg::LightSource> ls = new osg::LightSource();
  79.         ls->getLight()->setPosition(lightpos);

  80.         ls->getLight()->setAmbient(osg::Vec4(0.2,0.2,0.2,1.0));
  81.         ls->getLight()->setDiffuse(osg::Vec4(0.8,0.8,0.8,1.0));

  82.         return ls.get() ;
  83. }

  84. int main()
  85. {
  86.         osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

  87.         osg::ref_ptr<osg::Group> root = new osg::Group();

  88.     osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("cessna.osg");
  89.         cessna->setNodeMask(CastsShadowTraversalMask);
  90.         osg::ref_ptr<osg::Node> shadower = CreateShadowReceiverNode();
  91.         shadower->setNodeMask(ReceivesShadowTraversalMask);


  92.         //创建一个阴影节点,并标识接收对象和投影对象
  93.         osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene();
  94.         shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask);
  95.         shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask);

  96.         //创建阴影纹理
  97.         //osg::ref_ptr<osgShadow::SoftShadowMap> st = new osgShadow::SoftShadowMap();
  98.         osg::ref_ptr<osgShadow::ShadowMap> st = new osgShadow::ShadowMap();
  99.         //osg::ref_ptr<osgShadow::ShadowTexture> st = new osgShadow::ShadowTexture();
  100.         //关联阴影纹理
  101.         shadowedScene->setShadowTechnique(st);

  102.         osg::ref_ptr<osg::Group> node = new osg::Group() ;
  103.         node->addChild(cessna.get()) ;
  104.         node->addChild(shadower.get()) ;

  105.         //添加场景数据并添加光源
  106.         shadowedScene->addChild(CreateLight(node.get()));
  107.         shadowedScene->addChild(node.get());
  108.         root->addChild(shadowedScene.get());
  109.         //root->addChild(node.get());

  110.         //优化场景数据
  111.         osgUtil::Optimizer optimizer ;
  112.         optimizer.optimize(root.get()) ;

  113.         viewer->setSceneData(root.get());

  114.         viewer->realize();

  115.         viewer->run();

  116.         return 0 ;
  117. }
复制代码

该用户从未签到

发表于 2012-11-27 11:35:11 | 显示全部楼层
什么意思?您的阴影什么地方有问题?

该用户从未签到

 楼主| 发表于 2012-11-27 11:55:44 | 显示全部楼层
array 发表于 2012-11-27 11:35
什么意思?您的阴影什么地方有问题?

在花朵比较小的那张图上, 影子不全,在花外面的,应该还有一部分影子的 想飞机的机翼部分 就没有影子了

该用户从未签到

 楼主| 发表于 2012-11-28 10:55:34 | 显示全部楼层
array 发表于 2012-11-27 11:35
什么意思?您的阴影什么地方有问题?

array,可能我的问题讲述的不清,是这样的,我将一个影子投影到透明材质的板子上,这样影子是不会显示,不知道有没有方法解决这个问题。下面是我的代码
这个plane.osg是一个透明的板子,用来接收影子
  1. //创建一个光照
  2. osg::ref_ptr<osg::Node> CreateLight(osg::ref_ptr<osg::Node> model)
  3. {
  4.         osg::ComputeBoundsVisitor cbbv;
  5.         model->accept(cbbv);
  6.         osg::BoundingBox bb = cbbv.getBoundingBox();

  7.         osg::Vec4 lightpos;

  8.         lightpos.set(bb.center().x(), bb.center().y(), bb.zMax() + bb.radius()*2.0f  ,1.0f);

  9.         osg::ref_ptr<osg::LightSource> ls = new osg::LightSource();
  10.         ls->getLight()->setPosition(lightpos);

  11.         ls->getLight()->setAmbient(osg::Vec4(1.0,1.0,1.0,1.0));
  12.         ls->getLight()->setDiffuse(osg::Vec4(1.0,1.0,1.0,1.0));

  13.         return ls.get() ;
  14. }

  15. int main()
  16. {
  17.         osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

  18.         osg::ref_ptr<osg::Group> root = new osg::Group();

  19.             osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("cessna.osg");
  20.         cessna->setNodeMask(CastsShadowTraversalMask);
  21.         osg::ref_ptr<osg::Node> shadower = osgDB::readNodeFile("plane.osg"); //这个plane.osg是一个透明的板子,用来接收影子
  22.         shadower->setNodeMask(ReceivesShadowTraversalMask);


  23.         //创建一个阴影节点,并标识接收对象和投影对象
  24.         osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene();
  25.         shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask);
  26.         shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask);

  27.         //创建阴影纹理
  28.         //osg::ref_ptr<osgShadow::SoftShadowMap> st = new osgShadow::SoftShadowMap();
  29.         osg::ref_ptr<osgShadow::ShadowMap> st = new osgShadow::ShadowMap();
  30.         //osg::ref_ptr<osgShadow::ShadowTexture> st = new osgShadow::ShadowTexture();
  31.         //关联阴影纹理
  32.         shadowedScene->setShadowTechnique(st);

  33.         osg::ref_ptr<osg::Group> node = new osg::Group() ;
  34.         node->addChild(cessna.get()) ;
  35.         node->addChild(shadower.get()) ;

  36.         //添加场景数据并添加光源
  37.         shadowedScene->addChild(CreateLight(node.get()));
  38.         shadowedScene->addChild(node.get());
  39.         root->addChild(shadowedScene.get());
  40.         //root->addChild(node.get());

  41.         //优化场景数据
  42.         osgUtil::Optimizer optimizer ;
  43.         optimizer.optimize(root.get()) ;

  44.         viewer->setSceneData(root.get());

  45.         viewer->realize();

  46.         viewer->run();

  47.         return 0 ;
  48. }
复制代码
结果:
结果-没有影子.PNG

plane.osg

5.44 KB, 下载次数: 0, 下载积分: 威望 1

透明板子

该用户从未签到

发表于 2012-11-29 15:47:28 | 显示全部楼层
这不是矛盾的么,完全透明的物体上怎么可能投射出影子来。。。影子纹理的叠加并不会改变纹理本身的Alpha值,所以虽然影子叠加上了,但是融混之后还是整个像素都抛弃掉了。所以您这要求只能自己修改shader代码来实现了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表