日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

OSG学习:用多通道(multiple passes)实现透明度

發布時間:2023/12/13 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 OSG学习:用多通道(multiple passes)实现透明度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

osgFX庫提供了一個用于多通道渲染(multi-pass rendering)的框架。每個你想要渲染的子圖都應該被添加到osgFX::Effect節點,多通道技術的定義和使用都可以在這個節點中完成。你可能已經熟悉一些預定義的效果,例如osgFX::Scribe和osgFX::Outline。但是在這個教程中,我們的任務是我們自己設計一個多通道技術。這就是所謂的多通道透明度,當我們在透明模式(transparent mode)下它可以消除一些錯誤。

如何使用

添加必要的頭文件:

#include <osg/BlendFunc>
#include <osg/ColorMask>
#include <osg/Depth>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osgFX/Effect>
#include <osgViewer/Viewer>

2.首先,我們將提供一個新技術,這個技術繼承于osgFX::Technique節點。validate()方法是用于檢查現在硬件是否支持這個技術,如果一切正常會返回true。

class TransparencyTechnique : public osgFX::Technique
{
public:
TransparencyTechnique() : osgFX::Technique() {}
virtual bool validate( osg::State& ss ) const
{
return true;
}
protected:
virtual void define_passes();
};

3.在這個類中,另一個必須有的方法是define_passes()。這是用于定義多通道的。在這個教程中,我們將有兩個通道:一個是取消顏色掩膜(color mask)以及如果深度緩沖區值(depth buffer value)小于現在的就記錄下來;另一個將使用顏色緩沖區,但只有在深度值等于已經記錄下來的值的時候寫進去。(the second one will enable the useage of the color buffer but only to write to it when the depth value equals to the recorded one.)

osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
ss->setAttributeAndModes( new osg::ColorMask(
false, false, false, false) );
ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS) );
addPass( ss.get() );
ss = new osg::StateSet;
ss->setAttributeAndModes( new osg::ColorMask(
true, true, true, true) );
ss->setAttributeAndModes( new osg::Depth(osg::Depth::EQUAL) );
addPass( ss.get() );

我們設計完技術之后,現在我們可以聲明effect類,把技術添加到它的define_techniques()方法中。這里的META_Effect宏用于定義effect的基本方法:庫名,類名,作者名和描述。

class TransparencyNode : public osgFX::Effect
{
public:
TransparencyNode() : osgFX::Effect() {}
TransparencyNode( const TransparencyNode& copy,
const osg::CopyOp op=osg::CopyOp::SHALLOW_COPY )
: osgFX::Effect(copy, op) {}
META_Effect( osgFX, TransparencyNode, "TransparencyNode",
"", "" );
protected:
virtual bool define_techniques()
{
addTechnique(new TransparencyTechnique);
return true;
}
};

在main函數中,我們將使用景點的Cessna模型。不過,為了使它透明,我們將在上面添加一個新的材料,把散射顏色(diffuse color)的alpha通道設置為小于1的值,以及把TRANSPARENT_BIN這個hint應用到state set中。

osg::Node* loadedModel = osgDB::readNodeFile( "cessna.osg" );
osg::ref_ptr<osg::Material> material = new osg::Material;
material->setAmbient( osg::Material::FRONT_AND_BACK,
osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f) );
material->setDiffuse( osg::Material::FRONT_AND_BACK,
osg::Vec4(1.0f, 1.0f, 1.0f, 0.5f) );
loadedModel->getOrCreateStateSet()->setAttributeAndModes(
material.get(), osg::StateAttribute::ON|osg::StateAttribute::OVE
RRIDE );
loadedModel->getOrCreateStateSet()->setAttributeAndModes(
new osg::BlendFunc );
loadedModel->getOrCreateStateSet()->setRenderingHint(
osg::StateSet::TRANSPARENT_BIN );

6.創建一個新定義類的實例并添加到模型中。

osg::ref_ptr<TransparencyNode> fxNode = new TransparencyNode;
fxNode->addChild( loadedModel );
//Start the viewer now.
osgViewer::Viewer viewer;
viewer.setSceneData( fxNode.get() );
return viewer.run();

7.現在你將看到適當渲染過的透明的Cessna。

全部代碼:


#include <osg/BlendFunc>
#include <osg/ColorMask>
#include <osg/Depth>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osgFX/Effect>
#include <osgViewer/Viewer>

#include "CommonFunctions"

class TransparencyTechnique : public osgFX::Technique
{
public:
    TransparencyTechnique() : osgFX::Technique() {}
    virtual bool validate( osg::State& ss ) const { return true; }

protected:
    virtual void define_passes()
    {
        osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
        ss->setAttributeAndModes( new osg::ColorMask(false, false, false, false) );
        ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS) );
        addPass( ss.get() );

        ss = new osg::StateSet;
        ss->setAttributeAndModes( new osg::ColorMask(true, true, true, true) );
        ss->setAttributeAndModes( new osg::Depth(osg::Depth::EQUAL) );
        addPass( ss.get() );
    }
};

class TransparencyNode : public osgFX::Effect
{
public:
    TransparencyNode() : osgFX::Effect() {}
    TransparencyNode( const TransparencyNode& copy, const osg::CopyOp op=osg::CopyOp::SHALLOW_COPY )
    :   osgFX::Effect(copy, op) {}

    META_Effect( osgFX, TransparencyNode, "TransparencyNode", "", "" );

protected:
    virtual bool define_techniques()
    { addTechnique(new TransparencyTechnique); return true; }
};

int main( int argc, char** argv )
{
    osg::Node* loadedModel = osgDB::readNodeFile( "cessna.osg" );

    osg::ref_ptr<osg::Material> material = new osg::Material;
    material->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f) );
    material->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 1.0f, 1.0f, 0.5f) );
    loadedModel->getOrCreateStateSet()->setAttributeAndModes(
        material.get(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE );
    loadedModel->getOrCreateStateSet()->setAttributeAndModes( new osg::BlendFunc );
    loadedModel->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

    osg::ref_ptr<TransparencyNode> fxNode = new TransparencyNode;
    fxNode->addChild( loadedModel );

    osgViewer::Viewer viewer;
    viewer.setSceneData( fxNode.get() );
    return viewer.run();
}

原理

多通道透明度技術會繪制物體兩次。第一個通道(見后面代碼)僅僅更新深度緩沖區(depth buffer),以及找到最前面的多邊形:

osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
ss->setAttributeAndModes( new osg::ColorMask(
false, false, false, false) );
ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS) );
addPass( ss.get() );

第二個通道將會繪制進顏色緩沖區(color buffer),但由于在第一個通道中設置的深度值,只有前面的多邊形能夠通過深度檢測,它們的顏色將被繪制,與現在的混合。這避免了我們之前討論過的順序問題。代碼片段如下:

ss = new osg::StateSet;
ss->setAttributeAndModes( new osg::ColorMask(
true, true, true, true) );
ss->setAttributeAndModes( new osg::Depth(osg::Depth::EQUAL) );
addPass( ss.get() );

選自《OSG3 Cookbook》第六章

總結

以上是生活随笔為你收集整理的OSG学习:用多通道(multiple passes)实现透明度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。