OpenSceneGraph:绘制半透明对象时不要更新 z 缓冲区



问题

是否可以告诉 OpenSceneGraph 使用 Z 缓冲区,但在绘制半透明对象时不更新它?

赋予动机

绘制半透明对象时,绘制它们的顺序很重要,因为如果以错误的顺序绘制,本应可见的曲面可能会被遮挡。在某些情况下,OpenSceneGraph自己关于对象绘制顺序的直觉失败了 - 半透明表面被其他半透明表面遮挡,并且当OSG认为对象中心到相机的距离顺序已更改并决定更改渲染顺序时,可能会发生"弹出"(如果该词可以以这种方式使用(。因此,有必要通过使用状态集上的setRenderBinDetails方法手动指定每个对象的渲染箱来手动控制半透明对象的呈现顺序。

然而,这可能并不总是有效,因为在一般情况下,不可能为对象选择渲染顺序(即使场景中的各个三角形是有序的(,以便正确绘制所有片段(参见例如画家的问题(,并且仍然可能会被遮挡。另一种方法是使用深度剥离或其他一些与顺序无关的透明方法,但坦率地说,我不知道在 OpenSceneGraph 中实现这有多难,或者它会减慢应用程序的速度。

就我而言,作为美学与算法复杂性和速度之间的权衡,理想情况下,我总是想绘制半透明表面的片段,即使已经绘制了另一个半透明表面的另一个片段(在该像素中(更接近相机。这将防止其他半透明表面弹出和遮挡半透明表面,并且如果对于渲染的每个半透明对象,Z 缓冲区用于测试可见性但在绘制片段时未更新,则可以有效地实现。

你完全走在正确的轨道上。

是的,可以保持启用 Z 测试,但在绘制过程中关闭 Z 写入并setWriteMask()

// Disable Z-writes
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setWriteMask(false);
myNode->getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON)
// Enable Z-test (needs to be done after Z-writes are disabled, since the latter
// also seems to disable the Z-test)
myNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);

https://www.mail-archive.com/osg-users@openscenegraph.net/msg01119.html

http://public.vrac.iastate.edu/vancegroup/docs/OpenSceneGraphReferenceDocs-2.8/a00206.html#a2cef930c042c5d8cda32803e5e832dae

您可能希望查看我们几年前为CAD客户端编写的osgTransparencyTool nodekit:https://github.com/XenonofArcticus/OSG-Transparency-Tool

它包括几种透明度方法,您可以使用场景进行测试并检查其源实现,包括与顺序无关的透明度深度剥离实现和受 Open Inventor 启发的延迟混合方法。延迟混合是一种高性能单通道未排序近似,如果绝对透明度精度不是最重要的标准,则可能会选中您想要的所有框。

如果你还没有读过,这里有一篇详细讨论各种方法的论文: http://lips.informatik.uni-leipzig.de/files/bathesis_cbluemel_digital_0.pdf

相关内容

  • 没有找到相关文章

最新更新