OpenSceneGraph просто отбрасывает тень от одного из источников света в сцене.

Я пытаюсь добавить в сцену разные источники света и заставить их отбрасывать тени одновременно. Проблема в том, что каждый раз, когда я создаю новый osgShadow :: ShadowMap для источника света, предыдущий источник света перестает отбрасывать тень. Я подозреваю, что это как-то связано с индексом или чем-то в этом роде, точно так же, как для каждого источника света должен быть определен setLightNum (x). Ниже приведен код, используемый в качестве ссылки для этого изображения:  печатное изображение .

// * Copyright (c) 1982, 1986, 1990, 1991, 1993
// *      The Regents of the University of California.  All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions
// * are met:
// * 1. Redistributions of source code must retain the above copyright
// *    notice, this list of conditions and the following disclaimer.
// * 2. Redistributions in binary form must reproduce the above copyright
// *    notice, this list of conditions and the following disclaimer in the
// *    documentation and/or other materials provided with the distribution.
// * 3. All advertising materials mentioning features or use of this software
// *    must display the following acknowledgement:
// *      This product includes software developed by the University of
// *      California, Berkeley and its contributors.
// * 4. Neither the name of the University nor the names of its contributors
// *    may be used to endorse or promote products derived from this software
// *    without specific prior written permission.
// *
// * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
// * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
// * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// * SUCH DAMAGE.

#include <iostream>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Node>
#include <osg/ref_ptr>
#include <osg/LightModel>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Material>
#include <osg/Texture2D>
#include <osg/PositionAttitudeTransform>
#include <osg/Group>
#include <osg/MatrixTransform>
#include <osg/LightSource>
#include <osgShadow/ShadowedScene>
#include <osgShadow/ShadowMap>


#define LIGHT_CUTOFF_ANGLE 15
#define FILE_PATH_1 "tank.osg"
#define FILE_PATH_2 "rov.osg"


osg::Node* createLightSource(unsigned int num,
                             const osg::Vec3& trans,
                             const osg::Vec4& color)
{
    osg::ref_ptr<osg::Light> light = new osg::Light;
    light->setLightNum(num);
    light->setDiffuse(color);
    light->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
    osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource;
    lightSource->setLight(light);
    osg::ref_ptr<osg::MatrixTransform> sourceTrans = new osg::MatrixTransform;
    sourceTrans->setMatrix(osg::Matrix::translate(trans));
    sourceTrans->addChild(lightSource.get());
    return sourceTrans.release();
}

int main(int argc, char const *argv[])
{
    // Set masks of shadow receivers and casters
    unsigned int rcvShadowMask = 0x1;
    unsigned int castShadowMask = 0x2;

    // Tank
    osg::ref_ptr<osg::MatrixTransform> tankNode = new osg::MatrixTransform;
    tankNode->addChild(osgDB::readNodeFile(FILE_PATH_1));
    tankNode->setMatrix(osg::Matrix::translate(0.0f, 0.0f, 0.0f));
    tankNode->setNodeMask(rcvShadowMask|castShadowMask);

    // ROV
    osg::ref_ptr<osg::MatrixTransform> rovNode = new osg::MatrixTransform;
    rovNode->addChild( osgDB::readNodeFile(FILE_PATH_2));
    rovNode->setMatrix(osg::Matrix::translate(5.0f, 5.0f, -1.0f));
    rovNode->setNodeMask(rcvShadowMask|castShadowMask);

    // Ambient light (taken from book)
    osg::ref_ptr<osg::LightSource> source0 = new osg::LightSource;
    source0->getLight()->setPosition(osg::Vec4(5.0, 5.0, 9.0, 0.0));
    source0->getLight()->setAmbient(osg::Vec4(0.2, 0.2, 0.2, 1.0));
    source0->getLight()->setDiffuse(osg::Vec4(0.8, 0.8, 0.8, 1.0));

    // We choose the famous and effective shadow mapping (osgShadow::ShadowMap) technique, and set its
    // necessary parameters including the light source, shadow texture's size, and unit:
    osg::ref_ptr<osgShadow::ShadowMap> sm0 = new osgShadow::ShadowMap;
    sm0->setLight(source0.get());
    sm0->setTextureSize(osg::Vec2s(1024, 1024));
    sm0->setTextureUnit(1);

    //Set the shadow scene's root node, and apply the technique instance, as well as shadow masks to it:
    osg::ref_ptr<osgShadow::ShadowedScene> root = new osgShadow::ShadowedScene;
    root->setShadowTechnique(sm0.get());
    root->setReceivesShadowTraversalMask(rcvShadowMask);
    root->setCastsShadowTraversalMask(castShadowMask);

    // Create a light state set
    osg::StateSet* state = root->getOrCreateStateSet();

/*     state->setMode(GL_LIGHTING, osg::StateAttribute::ON);
    state->setMode(GL_LIGHT0, osg::StateAttribute::ON); */
    state->setMode(GL_LIGHT1, osg::StateAttribute::ON);
/*     state->setMode(GL_LIGHT2, osg::StateAttribute::ON);
    state->setMode(GL_LIGHT3, osg::StateAttribute::ON); */

    // 1st Light Cone
     osg::ref_ptr<osg::Light> light1 = new osg::Light();
    light1->setAmbient(osg::Vec4(0.1, 0.1, 0.1, 0.5));
    light1->setPosition(osg::Vec4(4.0, 4.0, 9.0, 1.0));
    light1->setDirection(osg::Vec3(0, 0, -1)); 
    light1->setSpotCutoff(LIGHT_CUTOFF_ANGLE);
    light1->setLightNum(1);
    osg::ref_ptr<osg::LightSource> source1 = new osg::LightSource();
    source1->setLight(light1.get());

    // We may have many lights, but only one of them will cast shadows so far.
    // Uncomment the ShadowMap lines to see this behavior.
/*     osg::ref_ptr<osgShadow::ShadowMap> sm1 = new osgShadow::ShadowMap;
    sm1->setLight(source1.get());   
    sm1->setTextureSize(osg::Vec2s(1024, 1024));
    sm1->setTextureUnit(1);
    root->setShadowTechnique(sm1.get());  */

    // Add all models and the light source to the root
    root->addChild(tankNode.get());
    root->addChild(rovNode.get());
    root->addChild(source0.get());
    root->addChild(source1.get());

    // Start the viewer
    osgViewer::Viewer viewer;
    viewer.setSceneData(root.get());
    return viewer.run();
}

Почему я не получаю тень от каждого источника света? Что мне здесь не хватает?

Заранее спасибо!


person Scott    schedule 15.01.2019    source источник


Ответы (1)


Вы используете для этого неправильный метод. Чтобы разрешить использование нескольких источников света, используйте:

osgShadow::ViewDependentShadowMap* sm0 = new osgShadow::ViewDependentShadowMap;

помимо

    osg::ref_ptr<osgShadow::ShadowMap> sm0 = new osgShadow::ShadowMap;
    sm0->setLight(source0.get());
    sm0->setTextureSize(osg::Vec2s(1024, 1024));
    sm0->setTextureUnit(1);

См .: http://www.openscenegraph.org/index.php/documentation/guides/programming-guides/108-shadows.

person Eberty Alves    schedule 24.05.2019