0
我是新的使用OSG,我有一些問題試圖解決問題。OpenSceneGraph - 隱形Cloack
我創建了一個場景(一個四邊形和兩個球體,有一個固定的背景),我試圖用透明四邊形遮擋其中一個球體。我的意思是,製作一張「隱形衣」,所以我可以通過它看到背景圖像,但不能看到它背後的球體(或任何在投影線中的物體)。
我完全卡住了,因爲我一直在做的所有測試都沒有讓我接近我想要的東西。如果你能幫助我,我會非常感激,任何想法(或代碼!)都會比歡迎! =)
我附上了我用來做測試的簡單場景的代碼。
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Depth>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/ShapeDrawable>
#include <osg/BlendFunc>
#include <osgGA/TrackBallManipulator>
int main()
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("C:/OpenSceneGraph-3.4.0/esc.jpg");
texture->setDataVariance(osg::Object::DYNAMIC);
texture->setResizeNonPowerOfTwoHint(false);
texture->setImage(image.get());
// Background
osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(osg::Vec3(),osg::Vec3(1.0f,0.0f,0.0f),osg::Vec3(0.0f, 1.0f, 0.0f));
quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get());
osg::ref_ptr<osg::Geode> geodeBack = new osg::Geode;
geodeBack->addDrawable(quad.get());
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setCullingActive(false);
camera->setClearMask(0);
camera->setAllowEventFocus(false);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));
camera->addChild(geodeBack.get());
osg::StateSet* ss = camera->getOrCreateStateSet();
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
ss->setMode(GL_DEPTH, osg::StateAttribute::ON);
ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL,0.99,1.0));
// Quad geometry
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, 1.0f,-1.0f));
vertices->push_back(osg::Vec3(0.0f, 1.0f,-1.0f));
vertices->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 0.0f));
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f,-1.0f, 0.0f));
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
osg::ref_ptr<osg::Geometry> quad2 = new osg::Geometry;
quad2->setVertexArray(vertices.get());
quad2->setNormalArray(normals.get());
quad2->setNormalBinding(osg::Geometry::BIND_OVERALL);
quad2->setColorArray(colors.get());
quad2->setColorBinding(osg::Geometry::BIND_OVERALL);
quad2->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
osg::ref_ptr<osg::Geode> geodeTransp = new osg::Geode;
geodeTransp->addDrawable(quad2.get());
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc;
blendFunc->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
osg::StateSet* stateset = geodeTransp->getOrCreateStateSet();
stateset->setAttributeAndModes(blendFunc);
// I'd see both spheres if I uncomment this. Otherwise I'd see the blue osg default background
//stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
// Sphere 1
osg::ref_ptr<osg::ShapeDrawable> shape1 = new osg::ShapeDrawable;
shape1->setShape(new osg::Sphere(osg::Vec3(-0.3f,0.5f,-0.3f), 0.2f));
shape1->setColor(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
// Sphere 2
osg::ref_ptr<osg::ShapeDrawable> shape2 = new osg::ShapeDrawable;
shape2->setShape(new osg::Sphere(osg::Vec3(-0.7f,1.5f,-0.7f), 0.2f));
shape2->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
osg::ref_ptr<osg::Geode> geodeFront = new osg::Geode;
geodeFront->addDrawable(shape1.get());
geodeFront->addDrawable(shape2.get());
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(camera.get());
root->addChild(geodeTransp.get());
root->addChild(geodeFront.get());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
osg::Vec3d eye(-0.5, -3.0, -0.5);
osg::Vec3d center(-0.5, 0.0, -0.5);
osg::Vec3d up(0.0, 0.0, 1.0);
viewer.getCamera()->setViewMatrixAsLookAt(eye, center, up);
viewer.realize();
while(!viewer.done()) {
viewer.frame();
}
return 0;
}
由於提前,
乾杯, 阿爾瓦羅
您好rickyviking,感謝您的快速響應! 真的很感激 但是,即使設置你告訴我渲染次序,它不斷髮生,我認爲 1.如果提供TRANSPARENT_BIN呈現提示:這兩個領域呈現,而不只是最近的一個。 2.如果我不知道,我可以看到的是通過四邊形表面的藍色osg默認背景,而不是我的固定背景。 ----- (也許任何一種渲染實心四邊形+渲染球體後將其狀態集更新爲透明?最近渲染背景?) – AVGrimaldi
對不起@AVGrimaldi,但這裏也有涉及的許多概念無法在單個問題中澄清。我在回答中提到的渲染順序應該會給你正確的結果。但是您需要更好地瞭解osg:TRANSPARENT_BIN會將對象排在前面,而不是您之後的對象,並且在渲染一幀時無法更改狀態集。檢查osg檔案和正確用法的例子 – rickyviking
太棒了,一定會做!雖然我仍然陷入困境......因爲你的答案也導致了「四重背景擦除」! (即使在任何情況下都不使用transparent_bin,正如你已經解釋的那樣),所以一定有一些缺失,爲了保持背景自定義圖像完好無損... – AVGrimaldi