Compositor: Enable small feature and view frustum culling by default for every pass. Added option to inherit the view master camera cull mask.

This commit is contained in:
Fernando García Liñán
2019-02-23 23:25:06 +01:00
parent 487cdc85cd
commit e2bed86bfc
4 changed files with 29 additions and 77 deletions

View File

@@ -126,6 +126,17 @@ Compositor::update(const osg::Matrix &view_matrix,
const osg::Matrix &proj_matrix)
{
for (auto &pass : _passes) {
if (pass->inherit_cull_mask) {
osg::Camera *camera = pass->camera;
osg::Camera *view_camera = _view->getCamera();
camera->setCullMask(pass->cull_mask
& view_camera->getCullMask());
camera->setCullMaskLeft(pass->cull_mask
& view_camera->getCullMaskLeft());
camera->setCullMaskRight(pass->cull_mask
& view_camera->getCullMaskRight());
}
if (pass->update_callback.valid())
pass->update_callback->updatePass(*pass.get(), view_matrix, proj_matrix);
}
@@ -189,20 +200,6 @@ Compositor::resized()
}
}
void
Compositor::setCameraCullMasks(osg::Node::NodeMask nm)
{
for (const auto &pass : _passes) {
osg::Camera *camera = pass->camera;
osg::Node::NodeMask pass_cm = nm;
pass_cm &= pass->cull_mask;
camera->setCullMask(pass_cm);
camera->setCullMaskLeft(pass_cm);
camera->setCullMaskRight(pass_cm);
}
}
bool
Compositor::computeIntersection(
const osg::Vec2d& windowPos,

View File

@@ -91,8 +91,6 @@ public:
void resized();
void setCameraCullMasks(osg::Node::NodeMask nm);
bool computeIntersection(
const osg::Vec2d& windowPos,
osgUtil::LineSegmentIntersector::Intersections& intersections);

View File

@@ -68,9 +68,6 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root)
if (!eff_override_file.empty())
pass->effect_override = makeEffect(eff_override_file, true, 0);
pass->cull_mask = std::stoul(root->getStringValue("cull-mask", "0xffffff"),
nullptr, 0);
osg::Camera *camera = new Camera;
pass->camera = camera;
@@ -83,6 +80,17 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root)
camera->setProjectionResizePolicy(osg::Camera::FIXED);
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
// XXX: Should we make this configurable?
camera->setCullingMode(CullSettings::SMALL_FEATURE_CULLING
| CullSettings::VIEW_FRUSTUM_CULLING);
osg::Node::NodeMask cull_mask =
std::stoul(root->getStringValue("cull-mask", "0xffffffff"), nullptr, 0);
pass->cull_mask = cull_mask;
camera->setCullMask(pass->cull_mask);
camera->setCullMaskLeft(pass->cull_mask);
camera->setCullMaskRight(pass->cull_mask);
osg::Vec4f clear_color(0.0f, 0.0f, 0.0f, 0.0f);
const SGPropertyNode *p_clear_color = root->getChild("clear-color");
if (p_clear_color)
@@ -265,7 +273,6 @@ struct QuadPassBuilder : public PassBuilder {
public:
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
pass->useMastersSceneData = false;
osg::Camera *camera = pass->camera;
camera->setAllowEventFocus(false);
@@ -367,62 +374,6 @@ RegisterPassBuilder<QuadPassBuilder> registerQuadPass("quad");
//------------------------------------------------------------------------------
#if 0
class ShadowMapUpdateCallback; // Forward declaration
class ShadowMapCullCallback : public osg::NodeCallback {
public:
ShadowMapCullCallback(int light_num, float near_m, float far_m) :
_light_num(light_num),
_near_m(near_m),
_far_m(far_m) {}
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) {
osg::Camera *light_camera = static_cast<osg::Camera *>(node);
osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(nv);
osg::Vec4 light_pos = _light->getPosition();
if (light_pos.w() != 0.0) {
// We only support directional light sources for now
traverse(node, nv);
return;
}
osg::Vec3 light_dir =
osg::Vec3(light_pos.x(), light_pos.y(), light_pos.z());
// Find the light
// Mostly taken from osgShadow
osgUtil::RenderStage *rs = cv->getRenderStage();
osgUtil::PositionalStateContainer::AttrMatrixList &aml =
rs->getPositionalStateContainer()->getAttrMatrixList();
for (auto &itr : aml) {
const osg::Light *light = dynamic_cast<const osg::Light *>(itr.first.get());
if (light) {
if (light->getLightNum() != _light_num)
continue;
osg::Vec4 light_pos = light->getPosition();
if (light_pos.w() == 0.0) {
// We only want directional lights
light_dir = osg::Vec3(light_pos.x(), light_pos.y(), light_pos.z());
}
}
}
traverse(node, nv);
}
protected:
friend ShadowMapUpdateCallback;
int _light_num;
float _near_m;
float _far_m;
osg::Matrix _camera_view;
osg::Matrix _camera_proj;
osg::observer_ptr<osg::Light> _light;
osg::ref_ptr<osg::Uniform> _light_matrix_uniform;
};
#endif
class LightFinder : public osg::NodeVisitor {
public:
LightFinder(const std::string &name) :
@@ -565,6 +516,7 @@ protected:
struct ShadowMapPassBuilder : public PassBuilder {
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
pass->useMastersSceneData = true;
osg::Camera *camera = pass->camera;
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
@@ -676,6 +628,8 @@ struct ScenePassBuilder : public PassBuilder {
public:
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
pass->useMastersSceneData = true;
pass->inherit_cull_mask = true;
osg::Camera *camera = pass->camera;
camera->setAllowEventFocus(true);

View File

@@ -45,8 +45,9 @@ class Compositor;
*/
struct Pass : public osg::Referenced {
Pass() :
useMastersSceneData(true),
useMastersSceneData(false),
cull_mask(0xffffff),
inherit_cull_mask(false),
viewport_width_scale(0.0f),
viewport_height_scale(0.0f) {}
@@ -57,6 +58,8 @@ struct Pass : public osg::Referenced {
osg::ref_ptr<Effect> effect_override;
bool useMastersSceneData;
osg::Node::NodeMask cull_mask;
/** Whether the cull mask is ANDed with the view master camera cull mask. */
bool inherit_cull_mask;
float viewport_width_scale;
float viewport_height_scale;