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:
@@ -126,6 +126,17 @@ Compositor::update(const osg::Matrix &view_matrix,
|
|||||||
const osg::Matrix &proj_matrix)
|
const osg::Matrix &proj_matrix)
|
||||||
{
|
{
|
||||||
for (auto &pass : _passes) {
|
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())
|
if (pass->update_callback.valid())
|
||||||
pass->update_callback->updatePass(*pass.get(), view_matrix, proj_matrix);
|
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
|
bool
|
||||||
Compositor::computeIntersection(
|
Compositor::computeIntersection(
|
||||||
const osg::Vec2d& windowPos,
|
const osg::Vec2d& windowPos,
|
||||||
|
|||||||
@@ -91,8 +91,6 @@ public:
|
|||||||
|
|
||||||
void resized();
|
void resized();
|
||||||
|
|
||||||
void setCameraCullMasks(osg::Node::NodeMask nm);
|
|
||||||
|
|
||||||
bool computeIntersection(
|
bool computeIntersection(
|
||||||
const osg::Vec2d& windowPos,
|
const osg::Vec2d& windowPos,
|
||||||
osgUtil::LineSegmentIntersector::Intersections& intersections);
|
osgUtil::LineSegmentIntersector::Intersections& intersections);
|
||||||
|
|||||||
@@ -68,9 +68,6 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root)
|
|||||||
if (!eff_override_file.empty())
|
if (!eff_override_file.empty())
|
||||||
pass->effect_override = makeEffect(eff_override_file, true, 0);
|
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;
|
osg::Camera *camera = new Camera;
|
||||||
pass->camera = camera;
|
pass->camera = camera;
|
||||||
|
|
||||||
@@ -83,6 +80,17 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root)
|
|||||||
camera->setProjectionResizePolicy(osg::Camera::FIXED);
|
camera->setProjectionResizePolicy(osg::Camera::FIXED);
|
||||||
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
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);
|
osg::Vec4f clear_color(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
const SGPropertyNode *p_clear_color = root->getChild("clear-color");
|
const SGPropertyNode *p_clear_color = root->getChild("clear-color");
|
||||||
if (p_clear_color)
|
if (p_clear_color)
|
||||||
@@ -265,7 +273,6 @@ struct QuadPassBuilder : public PassBuilder {
|
|||||||
public:
|
public:
|
||||||
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
||||||
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
||||||
pass->useMastersSceneData = false;
|
|
||||||
|
|
||||||
osg::Camera *camera = pass->camera;
|
osg::Camera *camera = pass->camera;
|
||||||
camera->setAllowEventFocus(false);
|
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 {
|
class LightFinder : public osg::NodeVisitor {
|
||||||
public:
|
public:
|
||||||
LightFinder(const std::string &name) :
|
LightFinder(const std::string &name) :
|
||||||
@@ -565,6 +516,7 @@ protected:
|
|||||||
struct ShadowMapPassBuilder : public PassBuilder {
|
struct ShadowMapPassBuilder : public PassBuilder {
|
||||||
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
||||||
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
||||||
|
pass->useMastersSceneData = true;
|
||||||
|
|
||||||
osg::Camera *camera = pass->camera;
|
osg::Camera *camera = pass->camera;
|
||||||
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
|
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT);
|
||||||
@@ -676,6 +628,8 @@ struct ScenePassBuilder : public PassBuilder {
|
|||||||
public:
|
public:
|
||||||
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
virtual Pass *build(Compositor *compositor, const SGPropertyNode *root) {
|
||||||
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
osg::ref_ptr<Pass> pass = PassBuilder::build(compositor, root);
|
||||||
|
pass->useMastersSceneData = true;
|
||||||
|
pass->inherit_cull_mask = true;
|
||||||
|
|
||||||
osg::Camera *camera = pass->camera;
|
osg::Camera *camera = pass->camera;
|
||||||
camera->setAllowEventFocus(true);
|
camera->setAllowEventFocus(true);
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ class Compositor;
|
|||||||
*/
|
*/
|
||||||
struct Pass : public osg::Referenced {
|
struct Pass : public osg::Referenced {
|
||||||
Pass() :
|
Pass() :
|
||||||
useMastersSceneData(true),
|
useMastersSceneData(false),
|
||||||
cull_mask(0xffffff),
|
cull_mask(0xffffff),
|
||||||
|
inherit_cull_mask(false),
|
||||||
viewport_width_scale(0.0f),
|
viewport_width_scale(0.0f),
|
||||||
viewport_height_scale(0.0f) {}
|
viewport_height_scale(0.0f) {}
|
||||||
|
|
||||||
@@ -57,6 +58,8 @@ struct Pass : public osg::Referenced {
|
|||||||
osg::ref_ptr<Effect> effect_override;
|
osg::ref_ptr<Effect> effect_override;
|
||||||
bool useMastersSceneData;
|
bool useMastersSceneData;
|
||||||
osg::Node::NodeMask cull_mask;
|
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_width_scale;
|
||||||
float viewport_height_scale;
|
float viewport_height_scale;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user