Location>code7788 >text

OSG Development Notes (Thirty-nine): Model Transparency Implementation in OSG, Sphere Transparency Demo

Popularity:958 ℃/2024-12-12 20:19:18

preamble

  In OSG, translucent effects are needed for business such as some effects not being selected or included.
  This describes the semi-transparent implementation of OSG.

 

Demo

  请添加图片描述

 

open (non-secretive)

Functional overview

  Transparency effect plays an important role in 3D scenes, which can simulate natural phenomena such as glass, water, smoke, etc. and increase the level and realism of the scene. However, the realization of transparency effect is not easy, it involves complex rendering techniques and algorithms. OSG, as a powerful scene library, provides strong support for the realization of transparency effect.

Adjustment of material properties

  In OSG, the first step to realize the transparency effect is to adjust the material properties. Material properties determine the appearance characteristics of an object's surface, including color, gloss, reflectivity, and transparency. To realize the transparency effect, you need to set the transparency property of the material.
  The osg::Material class in OSG is used to set the material properties of an object. By adjusting the osg::Material::TRANSPARENCY property, we can control the transparency of the object. Also, we need to set the color property of the object and specify the RGBA component of the color, where the A component indicates transparency.

Depth test setup

  Depth testing is an important technique in 3D rendering that is used to determine the front-to-back relationship of objects in the scene. The setting of the depth test is especially critical when implementing transparency effects. It is necessary to make sure that the depth test is turned on in order to correctly handle the occlusion of transparent objects in relation to the background or other objects. However, due to the partially occluded nature of transparent objects, the depth write (GL_DEPTH_WRITEMASK) setting also needs to be considered. In some cases, turning off depth writing can avoid depth conflict problems when rendering transparent objects.

Control of the rendering sequence

  The order in which transparent objects are rendered has a significant impact on their final rendering. In order to get the right rendering effect, we need to make sure that transparent objects are rendered in order from far to near, and OSG provides a transparency ordering mechanism to help us achieve this goal.
  By setting the osg::StateSet::TRANSPARENT_BIN rendering hint, we can add transparent objects to a separate rendering queue. osg will render these objects in order from farest to nearest, thus ensuring correct rendering results.

Mixed-mode applications

  Blending mode is one of the key techniques for achieving transparency effects. It determines how the color of a transparent object is calculated when it is mixed with the background or other objects. In OSG, we can specify the blend mode by setting the osg::BlendFunc property.
  Common blending modes include weighted sum of source color and destination color, difference of source color and destination color, and so on. By choosing the appropriate blending modes, we can get different transparency effects. For example, using GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA as the blending factors, we can realize the standard transparency blending effect.
  In OpenSceneGraph (OSG), implementing transparency effects usually involves adjusting material properties, depth test settings, and rendering order.
  To set the object transparent, it is by adjusting the transparency property of the material. osg::Material class is used to set the material property of the object, where osg::Material::TRANSPARENCY property can be used to set the transparency.

Basic realization process

  • Creating material instances, realized through materials (not conventional thinking RGBA, since A is not valid here)
  • Material instances set the material color, the material color is only valid for RGB, A is invalid.
  • Sets the transparency of the material instance
  • Get the set of model states for a model (which needs to be transparent)
  • Deep testing of the state set opening model
  • State set sets transparent channels to be rendered separately
  • State Set Setting Mixed Setting Mode

caveat

  • Ensure that transparent objects are in the correct order in the render queue.OSG's transparent sorting mechanism can help with this, but in some complex scenes you may need to manually control the render order.
  • The settings of Depth Write (GL_DEPTH_WRITEMASK) and Depth Test (GL_DEPTH_TEST) affect the rendering of transparent objects.
  • The setting of the blend mode (osg::BlendFunc) affects how transparent objects are blended with the background or other objects.

  With the above steps, it should be possible to implement basic transparency effects in OpenSceneGraph. If more advanced transparency processing is needed, you can further explore OSG's render queue and blend mode settings.

 

Transparent realization steps

Step 1: Get the state set

  在这里插入图片描述

// Step 1: Get the state set
osg::ref_ptr<osg::StateSet> pStateSet = pNode->getOrCreateStateSet();

Step 2: Turn on Deep Testing

  在这里插入图片描述

// Step 2: State Set Set the depth test on to ensure that the depth test for transparent objects is on
pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);

Step 3: Create a material instance

  在这里插入图片描述

// Step 3: Create the material instance
osg::ref_ptr<osg::Material> pMaterial = new osg::Material;

Step 4: Set the material color (theoretically the a of this is invalid)

  在这里插入图片描述

// Step 4: Material Instance Set the material color (RGB portion) and transparency in the color array
pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(color.x, color.y, color.z, color.a));

Step 5: Set material transparency (theoretically controlled from here)

  在这里插入图片描述

// Step 5: Material Example Setting Transparency (0-255): No graphics if set
pMaterial->setTransparency(osg::Material::FRONT_AND_BACK, color.a * 255.0);
//    pMaterial->setTransparency(osg::Material::FRONT_AND_BACK, 255.0);

Step 6: Setting the material

  在这里插入图片描述

// Step 6: State Set Set the material
pStateSet->setAttributeAndModes(pMaterial.get());

Step 7: Setting up the Transparent Channel for Individual Rendering

  在这里插入图片描述

// Step 7: State Set Set the transparent channel to be rendered separately
pStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

Step 8: Setting the Render Blend Mode

  在这里插入图片描述

// Step 8: State Set Set the rendering blend mode
pStateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 

Demo Source Code

Related Function Code

osg::ref_ptr<osg::Geode> OsgManager::createSphere(Point3F center, double radius, double ratio)
{
    // Draw the sphere
// Step 1: Create an object osg::Geode that holds geometry information for the user.
    osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
    // Step 2: Create a class osg::TessellationHints that specifies the fineness and set the corresponding fineness.
    osg::ref_ptr<osg::TessellationHints> pHints = new osg::TessellationHints;
    pHints->setDetailRatio(ratio);
    // Step 3: Draw the geometry type (Geometry)
    pGeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(center.x, center.y, center.y), radius), pHints));

    return pGeode.get();
}

osg::ref_ptr<osg::Material> OsgManager::setTransparency(osg::Node *pNode, Point4F color)
{
#if 1
    // Setting transparency

// Step 1: Get the state set
    osg::ref_ptr<osg::StateSet> pStateSet = pNode->getOrCreateStateSet();
    // Step 2: State Set Set the depth test on to ensure that the depth test for transparent objects is on
    pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
    // Step 3: Create the material instance
    osg::ref_ptr<osg::Material> pMaterial = new osg::Material;
    // Step 4: Material Instance Set the material color (RGB portion) and transparency in the color array
    pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(color.x, color.y, color.z, color.a));
    // Step 5: Material Example Setting Transparency (0-255): no graphic when set.
//    pMaterial->setTransparency(osg::Material::FRONT_AND_BACK,  * 255.0);
//    pMaterial->setTransparency(osg::Material::FRONT_AND_BACK, 255.0);
    // Step 6: State Set Set the material
    pStateSet->setAttributeAndModes(pMaterial.get());
    // Step 7: State Set Set the transparent channel to be rendered separately
    pStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
    // Step 8: State Set Set the rendering blend mode
    pStateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
//    static int z = 0;
//    pStateSet->setRenderBinDetails(z++,QString("RenderBin%1").arg(z).toStdString());
#else
    osg::ref_ptr<osg::Material> pMaterial = new osg::Material;
    // Alpha blending on
    osg::ref_ptr<osg::StateSet> pStateSet = pNode->getOrCreateStateSet();
    //Cancel the depth test
    pStateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
    pStateSet->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF  );
    pStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
    pStateSet->setRenderBinDetails(11, "RenderBin");
#endif
    return pMaterial.get();
}

osg::ref_ptr<osg::Node> OsgWidget::getTransparency()
{
    // Controls for other demos
updateControlVisible(false);

    osg::ref_ptr<osg::Group> pGroup = new osg::Group();
    {
        // Create geometry
        osg::ref_ptr<osg::Geode> pGeode = OsgManager::createSphere(Point3F(0, 0, 0), 0.5);
        // Set transparency
        osg::ref_ptr<osg::Material> pMaterial = OsgManager::setTransparency(pGeode, Point4F(1.0, 1.0, 1.0, 0.8));

        pGroup->addChild(pGeode);
    }
#if 0
    {
        // Create geometry
        osg::ref_ptr<osg::Geode> pGeode = OsgManager::createSphere(Point3F(-1, 0, 0), 0.5);
        // Setting transparency
        osg::ref_ptr<osg::Material> pMaterial = OsgManager::setTransparency(pGeode, Point4F(1.0, 0.0, 0.0, 0.25));

        pGroup->addChild(pGeode);
    }
    {
        // Create geometry
        osg::ref_ptr<osg::Geode> pGeode = OsgManager::createSphere(Point3F(1, 0, 0), 0.5);
        // Setting transparency
        osg::ref_ptr<osg::Material> pMaterial = OsgManager::setTransparency(pGeode, Point4F(0.0, 1.0, 0.0, 0.25));

        pGroup->addChild(pGeode);
    }
    {
        // Create geometry
        osg::ref_ptr<osg::Geode> pGeode = OsgManager::createSphere(Point3F(0, -1, 0), 0.5);
        // Set transparency
        osg::ref_ptr<osg::Material> pMaterial = OsgManager::setTransparency(pGeode, Point4F(0.0, 0.0, 1.0, 0.50));


        pGroup->addChild(pGeode);
    }
    {