Preliminary changes for the HDR pipeline
- Add an Effect to stars and planets so they don't disappear when not using the fixed-pipeline. - Allow usage of the shadow mapping related uniforms in 'quad' passes as well. - Add extra buffer formats (some of them only work under the core profile). - Better handling of mipmapping in the Compositor.
This commit is contained in:
parent
877c3a68e6
commit
b3b863a3c4
@ -96,10 +96,10 @@ void SGSky::build( double h_radius_m,
|
||||
|
||||
pre_transform->addChild(_ephTransform.get());
|
||||
planets = new SGStars;
|
||||
_ephTransform->addChild( planets->build(eph.getNumPlanets(), eph.getPlanets(), h_radius_m) );
|
||||
_ephTransform->addChild( planets->build(eph.getNumPlanets(), eph.getPlanets(), h_radius_m, options) );
|
||||
|
||||
stars = new SGStars(property_tree_node);
|
||||
_ephTransform->addChild( stars->build(eph.getNumStars(), eph.getStars(), h_radius_m) );
|
||||
_ephTransform->addChild( stars->build(eph.getNumStars(), eph.getStars(), h_radius_m, options) );
|
||||
|
||||
moon = new SGMoon;
|
||||
_ephTransform->addChild( moon->build(tex_path, moon_size) );
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/material/Effect.hxx>
|
||||
#include <simgear/scene/material/EffectGeode.hxx>
|
||||
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
@ -48,6 +51,8 @@
|
||||
|
||||
#include "stars.hxx"
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
// Constructor
|
||||
SGStars::SGStars( SGPropertyNode* props ) :
|
||||
old_phase(-1)
|
||||
@ -67,8 +72,15 @@ SGStars::~SGStars( void ) {
|
||||
|
||||
// initialize the stars object and connect it into our scene graph root
|
||||
osg::Node*
|
||||
SGStars::build( int num, const SGVec3d star_data[], double star_dist ) {
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
SGStars::build( int num, const SGVec3d star_data[], double star_dist,
|
||||
SGReaderWriterOptions* options ) {
|
||||
EffectGeode* geode = new EffectGeode;
|
||||
geode->setName("Stars");
|
||||
|
||||
Effect* effect = makeEffect("Effects/stars", true, options);
|
||||
if (effect)
|
||||
geode->setEffect(effect);
|
||||
|
||||
osg::StateSet* stateSet = geode->getOrCreateStateSet();
|
||||
stateSet->setRenderBinDetails(-9, "RenderBin");
|
||||
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/props/propsfwd.hxx>
|
||||
|
||||
namespace simgear {
|
||||
class SGReaderWriterOptions;
|
||||
}
|
||||
|
||||
class SGStars : public SGReferenced {
|
||||
|
||||
osg::ref_ptr<osg::Vec4Array> cl;
|
||||
@ -52,7 +56,8 @@ public:
|
||||
~SGStars( void );
|
||||
|
||||
// initialize the stars structure
|
||||
osg::Node* build( int num, const SGVec3d star_data[], double star_dist );
|
||||
osg::Node* build( int num, const SGVec3d star_data[], double star_dist,
|
||||
simgear::SGReaderWriterOptions* options );
|
||||
|
||||
// repaint the planet magnitudes based on current value of
|
||||
// sun_angle in degrees relative to verticle (so we can make them
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "CompositorUtil.hxx"
|
||||
|
||||
|
||||
class LightDirectionCallback : public osg::Uniform::Callback {
|
||||
class SunDirectionCallback : public osg::Uniform::Callback {
|
||||
public:
|
||||
virtual void operator()(osg::Uniform *uniform, osg::NodeVisitor *nv) {
|
||||
SGUpdateVisitor *uv = dynamic_cast<SGUpdateVisitor *>(nv);
|
||||
@ -140,10 +140,10 @@ Compositor::Compositor(osg::View *view,
|
||||
new osg::Uniform("fg_CameraPositionGeod", osg::Vec3f()),
|
||||
new osg::Uniform("fg_NearFarPlanes", osg::Vec3f()),
|
||||
new osg::Uniform("fg_Fcoef", 0.0f),
|
||||
new osg::Uniform("fg_LightDirection", osg::Vec3f())
|
||||
new osg::Uniform("fg_SunDirection", osg::Vec3f())
|
||||
}
|
||||
{
|
||||
_uniforms[LIGHT_DIRECTION]->setUpdateCallback(new LightDirectionCallback);
|
||||
_uniforms[SUN_DIRECTION]->setUpdateCallback(new SunDirectionCallback);
|
||||
}
|
||||
|
||||
Compositor::~Compositor()
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
CAMERA_POSITION_GEOD,
|
||||
NEAR_FAR_PLANES,
|
||||
FCOEF,
|
||||
LIGHT_DIRECTION,
|
||||
SUN_DIRECTION,
|
||||
TOTAL_BUILTIN_UNIFORMS
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "CompositorBuffer.hxx"
|
||||
|
||||
#include <osg/GL>
|
||||
#include <osg/Texture1D>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Texture2DArray>
|
||||
@ -23,7 +24,6 @@
|
||||
#include <osg/Texture3D>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osg/TextureCubeMap>
|
||||
#include <osg/FrameBufferObject>
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/props/vectorPropTemplates.hxx>
|
||||
@ -45,13 +45,18 @@ struct BufferFormat {
|
||||
PropStringMap<BufferFormat> buffer_format_map {
|
||||
{"rgb8", {GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE}},
|
||||
{"rgba8", {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}},
|
||||
{"rgb16f", {GL_RGB16F_ARB, GL_RGBA, GL_FLOAT}},
|
||||
{"rgb16f", {GL_RGB16F_ARB, GL_RGBA, GL_HALF_FLOAT}},
|
||||
{"rgb32f", {GL_RGB32F_ARB, GL_RGBA, GL_FLOAT}},
|
||||
{"rgba16f", {GL_RGBA16F_ARB, GL_RGBA, GL_FLOAT}},
|
||||
{"rgba16f", {GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT}},
|
||||
{"rgba32f", {GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT}},
|
||||
{"r8", {GL_R8, GL_RED, GL_UNSIGNED_BYTE}},
|
||||
{"r16f", {GL_R16F, GL_RED, GL_HALF_FLOAT}},
|
||||
{"r32f", {GL_R32F, GL_RED, GL_FLOAT}},
|
||||
{"rg16f", {GL_RG16F, GL_RG, GL_FLOAT}},
|
||||
{"rg16f", {GL_RG16F, GL_RG, GL_HALF_FLOAT}},
|
||||
{"rg32f", {GL_RG32F, GL_RG, GL_FLOAT}},
|
||||
#if defined(OSG_GL3_FEATURES)
|
||||
{"r11g11b10f", {GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT}},
|
||||
#endif
|
||||
{"depth16", {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}},
|
||||
{"depth24", {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}},
|
||||
{"depth32f", {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT}},
|
||||
@ -136,17 +141,32 @@ buildBuffer(Compositor *compositor, const SGPropertyNode *node,
|
||||
if (p_depth)
|
||||
depth = p_depth->getIntValue();
|
||||
|
||||
auto get_mipmap_levels = [&]() -> int {
|
||||
int mipmap_levels = 0;
|
||||
const SGPropertyNode *p_mipmap_levels = node->getNode("mipmap-levels");
|
||||
if (p_mipmap_levels) {
|
||||
if (p_mipmap_levels->getStringValue() == std::string("auto"))
|
||||
mipmap_levels = 1 + floor(log2((float)max(max(width, height), depth)));
|
||||
else
|
||||
mipmap_levels = p_mipmap_levels->getIntValue();
|
||||
}
|
||||
return mipmap_levels;
|
||||
};
|
||||
|
||||
if (type == "1d") {
|
||||
osg::Texture1D *tex1D = new osg::Texture1D;
|
||||
tex1D->setTextureWidth(width);
|
||||
tex1D->setNumMipmapLevels(get_mipmap_levels());
|
||||
texture = tex1D;
|
||||
} else if (type == "2d") {
|
||||
osg::Texture2D *tex2D = new osg::Texture2D;
|
||||
tex2D->setTextureSize(width, height);
|
||||
tex2D->setNumMipmapLevels(get_mipmap_levels());
|
||||
texture = tex2D;
|
||||
} else if (type == "2d-array") {
|
||||
osg::Texture2DArray *tex2D_array = new osg::Texture2DArray;
|
||||
tex2D_array->setTextureSize(width, height, depth);
|
||||
tex2D_array->setNumMipmapLevels(get_mipmap_levels());
|
||||
texture = tex2D_array;
|
||||
} else if (type == "2d-multisample") {
|
||||
osg::Texture2DMultisample *tex2DMS = new osg::Texture2DMultisample;
|
||||
@ -156,6 +176,7 @@ buildBuffer(Compositor *compositor, const SGPropertyNode *node,
|
||||
} else if (type == "3d") {
|
||||
osg::Texture3D *tex3D = new osg::Texture3D;
|
||||
tex3D->setTextureSize(width, height, depth);
|
||||
tex3D->setNumMipmapLevels(get_mipmap_levels());
|
||||
texture = tex3D;
|
||||
} else if (type == "rect") {
|
||||
osg::TextureRectangle *tex_rect = new osg::TextureRectangle;
|
||||
@ -164,6 +185,7 @@ buildBuffer(Compositor *compositor, const SGPropertyNode *node,
|
||||
} else if (type == "cubemap") {
|
||||
osg::TextureCubeMap *tex_cubemap = new osg::TextureCubeMap;
|
||||
tex_cubemap->setTextureSize(width, height);
|
||||
tex_cubemap->setNumMipmapLevels(get_mipmap_levels());
|
||||
texture = tex_cubemap;
|
||||
} else {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Unknown texture type '" << type << "'");
|
||||
@ -181,7 +203,8 @@ buildBuffer(Compositor *compositor, const SGPropertyNode *node,
|
||||
texture->setSourceType(format.source_type);
|
||||
} else {
|
||||
texture->setInternalFormat(GL_RGBA);
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Unknown buffer format specified, using RGBA");
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Unknown buffer format '"
|
||||
<< node->getStringValue("format") << "', using RGBA");
|
||||
}
|
||||
|
||||
osg::Texture::FilterMode filter_mode = osg::Texture::LINEAR;
|
||||
|
@ -55,6 +55,76 @@ PropStringMap<osg::Camera::BufferComponent> buffer_component_map = {
|
||||
{"packed-depth-stencil", osg::Camera::PACKED_DEPTH_STENCIL_BUFFER}
|
||||
};
|
||||
|
||||
class CSMCullCallback : public osg::NodeCallback {
|
||||
public:
|
||||
CSMCullCallback(const std::string &suffix) {
|
||||
_light_matrix_uniform = new osg::Uniform(
|
||||
osg::Uniform::FLOAT_MAT4, std::string("fg_LightMatrix_") + suffix);
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
||||
osg::Camera *camera = static_cast<osg::Camera *>(node);
|
||||
|
||||
traverse(node, nv);
|
||||
|
||||
// The light matrix uniform is updated after the traverse in case the
|
||||
// OSG near/far plane calculations were enabled
|
||||
osg::Matrixf light_matrix =
|
||||
// Include the real camera inverse view matrix because if the shader
|
||||
// used world coordinates, there would be precision issues.
|
||||
_real_inverse_view *
|
||||
camera->getViewMatrix() *
|
||||
camera->getProjectionMatrix() *
|
||||
// Bias matrices
|
||||
osg::Matrix::translate(1.0, 1.0, 1.0) *
|
||||
osg::Matrix::scale(0.5, 0.5, 0.5);
|
||||
_light_matrix_uniform->set(light_matrix);
|
||||
}
|
||||
|
||||
void setRealInverseViewMatrix(const osg::Matrix &matrix) {
|
||||
_real_inverse_view = matrix;
|
||||
}
|
||||
|
||||
osg::Uniform *getLightMatrixUniform() const {
|
||||
return _light_matrix_uniform.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::Matrix _real_inverse_view;
|
||||
osg::ref_ptr<osg::Uniform> _light_matrix_uniform;
|
||||
};
|
||||
|
||||
class LightFinder : public osg::NodeVisitor {
|
||||
public:
|
||||
LightFinder(const std::string &name) :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_name(name) {}
|
||||
virtual void apply(osg::Node &node) {
|
||||
// Only traverse the scene graph if we haven't found a light yet (or if
|
||||
// the one we found earlier is no longer valid).
|
||||
if (getLight().valid())
|
||||
return;
|
||||
|
||||
if (node.getName() == _name) {
|
||||
osg::LightSource *light_source =
|
||||
dynamic_cast<osg::LightSource *>(&node);
|
||||
if (light_source)
|
||||
_light = light_source->getLight();
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
osg::ref_ptr<osg::Light> getLight() const {
|
||||
osg::ref_ptr<osg::Light> light_ref;
|
||||
_light.lock(light_ref);
|
||||
return light_ref;
|
||||
}
|
||||
protected:
|
||||
std::string _name;
|
||||
osg::observer_ptr<osg::Light> _light;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Pass *
|
||||
PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
@ -128,7 +198,8 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
osg::DisplaySettings::ImplicitBufferAttachmentMask implicit_attachments = 0;
|
||||
std::stringstream att_ss;
|
||||
std::string att_bit;
|
||||
att_ss << root->getStringValue("implicit-attachment-mask", "color depth");
|
||||
// No implicit attachments by default
|
||||
att_ss << root->getStringValue("implicit-attachment-mask", "");
|
||||
while (att_ss >> att_bit) {
|
||||
if (att_bit == "color") implicit_attachments |= osg::DisplaySettings::IMPLICIT_COLOR_BUFFER_ATTACHMENT;
|
||||
else if (att_bit == "depth") implicit_attachments |= osg::DisplaySettings::IMPLICIT_DEPTH_BUFFER_ATTACHMENT;
|
||||
@ -136,6 +207,30 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
}
|
||||
camera->setImplicitBufferAttachmentMask(implicit_attachments, implicit_attachments);
|
||||
|
||||
// Set some global state
|
||||
camera->getOrCreateStateSet()->setMode(GL_TEXTURE_CUBE_MAP_SEAMLESS,
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
PropertyList p_shadow_passes = root->getChildren("use-shadow-pass");
|
||||
for (const auto &p_shadow_pass : p_shadow_passes) {
|
||||
std::string shadow_pass_name = p_shadow_pass->getStringValue();
|
||||
if (!shadow_pass_name.empty()) {
|
||||
Pass *shadow_pass = compositor->getPass(shadow_pass_name);
|
||||
if (shadow_pass) {
|
||||
CSMCullCallback *cullcb =
|
||||
dynamic_cast<CSMCullCallback *>(
|
||||
shadow_pass->camera->getCullCallback());
|
||||
if (cullcb) {
|
||||
camera->getOrCreateStateSet()->addUniform(
|
||||
cullcb->getLightMatrixUniform());
|
||||
} else {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "ScenePassBuilder::build: Pass '"
|
||||
<< shadow_pass_name << "is not a shadow pass");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyList p_bindings = root->getChildren("binding");
|
||||
for (auto const &p_binding : p_bindings) {
|
||||
if (!checkConditional(p_binding))
|
||||
@ -242,6 +337,7 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
multisample_samples,
|
||||
multisample_color_samples);
|
||||
|
||||
float mipmap_resize_factor = 1.0f / pow(2.0f, float(level));
|
||||
if (!viewport_absolute &&
|
||||
(p_attachment->getIndex() == viewport_attachment)) {
|
||||
if ((buffer->width_scale == 0.0f) &&
|
||||
@ -250,8 +346,10 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
// relative coordinates to shape the viewport.
|
||||
float x = p_viewport->getFloatValue("x", 0.0f);
|
||||
float y = p_viewport->getFloatValue("y", 0.0f);
|
||||
float width = p_viewport->getFloatValue("width", 1.0f);
|
||||
float height = p_viewport->getFloatValue("height", 1.0f);
|
||||
float width = p_viewport->getFloatValue("width", 1.0f)
|
||||
* mipmap_resize_factor;
|
||||
float height = p_viewport->getFloatValue("height", 1.0f)
|
||||
* mipmap_resize_factor;
|
||||
camera->setViewport(x * texture->getTextureWidth(),
|
||||
y * texture->getTextureHeight(),
|
||||
width * texture->getTextureWidth(),
|
||||
@ -260,13 +358,15 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
|
||||
// This is a pass that should match the physical viewport
|
||||
// size. Store the scales so we can resize the pass later
|
||||
// if the physical viewport changes size.
|
||||
pass->viewport_width_scale = buffer->width_scale;
|
||||
pass->viewport_height_scale = buffer->height_scale;
|
||||
pass->viewport_width_scale = buffer->width_scale
|
||||
* mipmap_resize_factor;
|
||||
pass->viewport_height_scale = buffer->height_scale
|
||||
* mipmap_resize_factor;
|
||||
camera->setViewport(
|
||||
0,
|
||||
0,
|
||||
buffer->width_scale * compositor->getViewport()->width(),
|
||||
buffer->height_scale * compositor->getViewport()->height());
|
||||
pass->viewport_width_scale * compositor->getViewport()->width(),
|
||||
pass->viewport_height_scale * compositor->getViewport()->height());
|
||||
}
|
||||
}
|
||||
} catch (sg_exception &e) {
|
||||
@ -332,6 +432,10 @@ public:
|
||||
for (const auto &uniform : compositor->getUniforms())
|
||||
ss->addUniform(uniform);
|
||||
|
||||
int cubemap_face = root->getIntValue("cubemap-face", -1);
|
||||
if (cubemap_face >= 0)
|
||||
ss->addUniform(new osg::Uniform("fg_CubemapFace", cubemap_face));
|
||||
|
||||
return pass.release();
|
||||
}
|
||||
protected:
|
||||
@ -388,75 +492,6 @@ RegisterPassBuilder<QuadPassBuilder> registerQuadPass("quad");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class CSMCullCallback : public osg::NodeCallback {
|
||||
public:
|
||||
CSMCullCallback(const std::string &suffix) {
|
||||
_light_matrix_uniform = new osg::Uniform(
|
||||
osg::Uniform::FLOAT_MAT4, std::string("fg_LightMatrix_") + suffix);
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
||||
osg::Camera *camera = static_cast<osg::Camera *>(node);
|
||||
|
||||
traverse(node, nv);
|
||||
|
||||
// The light matrix uniform is updated after the traverse in case the
|
||||
// OSG near/far plane calculations were enabled
|
||||
osg::Matrixf light_matrix =
|
||||
// Include the real camera inverse view matrix because if the shader
|
||||
// used world coordinates, there would be precision issues.
|
||||
_real_inverse_view *
|
||||
camera->getViewMatrix() *
|
||||
camera->getProjectionMatrix() *
|
||||
// Bias matrices
|
||||
osg::Matrix::translate(1.0, 1.0, 1.0) *
|
||||
osg::Matrix::scale(0.5, 0.5, 0.5);
|
||||
_light_matrix_uniform->set(light_matrix);
|
||||
}
|
||||
|
||||
void setRealInverseViewMatrix(const osg::Matrix &matrix) {
|
||||
_real_inverse_view = matrix;
|
||||
}
|
||||
|
||||
osg::Uniform *getLightMatrixUniform() const {
|
||||
return _light_matrix_uniform.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::Matrix _real_inverse_view;
|
||||
osg::ref_ptr<osg::Uniform> _light_matrix_uniform;
|
||||
};
|
||||
|
||||
class LightFinder : public osg::NodeVisitor {
|
||||
public:
|
||||
LightFinder(const std::string &name) :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_name(name) {}
|
||||
virtual void apply(osg::Node &node) {
|
||||
// Only traverse the scene graph if we haven't found a light yet (or if
|
||||
// the one we found earlier is no longer valid).
|
||||
if (getLight().valid())
|
||||
return;
|
||||
|
||||
if (node.getName() == _name) {
|
||||
osg::LightSource *light_source =
|
||||
dynamic_cast<osg::LightSource *>(&node);
|
||||
if (light_source)
|
||||
_light = light_source->getLight();
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
osg::ref_ptr<osg::Light> getLight() const {
|
||||
osg::ref_ptr<osg::Light> light_ref;
|
||||
_light.lock(light_ref);
|
||||
return light_ref;
|
||||
}
|
||||
protected:
|
||||
std::string _name;
|
||||
osg::observer_ptr<osg::Light> _light;
|
||||
};
|
||||
|
||||
struct CSMUpdateCallback : public Pass::PassUpdateCallback {
|
||||
public:
|
||||
CSMUpdateCallback(CSMCullCallback *cull_callback,
|
||||
@ -631,26 +666,26 @@ public:
|
||||
camera->setViewMatrix(view_matrix);
|
||||
camera->setProjectionMatrix(new_proj_matrix);
|
||||
} else {
|
||||
osg::Vec3 camera_pos = osg::Vec3(0.0, 0.0, 0.0) *
|
||||
osg::Matrix::inverse(view_matrix);
|
||||
osg::Vec4d camera_pos4 = osg::Vec4d(0.0, 0.0, 0.0, 1.0) *
|
||||
osg::Matrixd::inverse(view_matrix);
|
||||
osg::Vec3d camera_pos(camera_pos4.x(), camera_pos4.y(), camera_pos4.z());
|
||||
|
||||
typedef std::pair<osg::Vec3, osg::Vec3> CubemapFace;
|
||||
typedef std::pair<osg::Vec3d, osg::Vec3d> CubemapFace;
|
||||
const CubemapFace id[] = {
|
||||
CubemapFace(osg::Vec3( 1, 0, 0), osg::Vec3( 0, -1, 0)), // +X
|
||||
CubemapFace(osg::Vec3(-1, 0, 0), osg::Vec3( 0, -1, 0)), // -X
|
||||
CubemapFace(osg::Vec3( 0, 1, 0), osg::Vec3( 0, 0, 1)), // +Y
|
||||
CubemapFace(osg::Vec3( 0, -1, 0), osg::Vec3( 0, 0, -1)), // -Y
|
||||
CubemapFace(osg::Vec3( 0, 0, 1), osg::Vec3( 0, -1, 0)), // +Z
|
||||
CubemapFace(osg::Vec3( 0, 0, -1), osg::Vec3( 0, -1, 0)) // -Z
|
||||
CubemapFace(osg::Vec3d( 1.0, 0.0, 0.0), osg::Vec3d( 0.0, -1.0, 0.0)), // +X
|
||||
CubemapFace(osg::Vec3d(-1.0, 0.0, 0.0), osg::Vec3d( 0.0, -1.0, 0.0)), // -X
|
||||
CubemapFace(osg::Vec3d( 0.0, 1.0, 0.0), osg::Vec3d( 0.0, 0.0, 1.0)), // +Y
|
||||
CubemapFace(osg::Vec3d( 0.0, -1.0, 0.0), osg::Vec3d( 0.0, 0.0, -1.0)), // -Y
|
||||
CubemapFace(osg::Vec3d( 0.0, 0.0, 1.0), osg::Vec3d( 0.0, -1.0, 0.0)), // +Z
|
||||
CubemapFace(osg::Vec3d( 0.0, 0.0, -1.0), osg::Vec3d( 0.0, -1.0, 0.0)) // -Z
|
||||
};
|
||||
|
||||
osg::Matrix cubemap_view_matrix;
|
||||
osg::Matrixd cubemap_view_matrix;
|
||||
cubemap_view_matrix.makeLookAt(camera_pos,
|
||||
camera_pos + id[_cubemap_face].first,
|
||||
camera_pos + id[_cubemap_face].second);
|
||||
id[_cubemap_face].second);
|
||||
camera->setViewMatrix(cubemap_view_matrix);
|
||||
camera->setProjectionMatrixAsFrustum(-1.0, 1.0, -1.0, 1.0,
|
||||
znear, zfar);
|
||||
camera->setProjectionMatrixAsPerspective(90.0, 1.0, znear, zfar);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
@ -706,29 +741,10 @@ public:
|
||||
float zFar = root->getFloatValue("z-far", 0.0f);
|
||||
pass->update_callback = new SceneUpdateCallback(cubemap_face, zNear, zFar);
|
||||
|
||||
PropertyList p_shadow_passes = root->getChildren("use-shadow-pass");
|
||||
for (const auto &p_shadow_pass : p_shadow_passes) {
|
||||
std::string shadow_pass_name = p_shadow_pass->getStringValue();
|
||||
if (!shadow_pass_name.empty()) {
|
||||
Pass *shadow_pass = compositor->getPass(shadow_pass_name);
|
||||
if (shadow_pass) {
|
||||
CSMCullCallback *cullcb =
|
||||
dynamic_cast<CSMCullCallback *>(
|
||||
shadow_pass->camera->getCullCallback());
|
||||
if (cullcb) {
|
||||
camera->getOrCreateStateSet()->addUniform(
|
||||
cullcb->getLightMatrixUniform());
|
||||
} else {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "ScenePassBuilder::build: Pass '"
|
||||
<< shadow_pass_name << "is not a shadow pass");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::StateSet *ss = camera->getOrCreateStateSet();
|
||||
auto &uniforms = compositor->getUniforms();
|
||||
ss->addUniform(uniforms[Compositor::FCOEF]);
|
||||
ss->addUniform(uniforms[Compositor::SUN_DIRECTION]);
|
||||
|
||||
osg::ref_ptr<osg::Uniform> clustered_shading_enabled =
|
||||
new osg::Uniform("fg_ClusteredEnabled", clustered ? true : false);
|
||||
|
Loading…
Reference in New Issue
Block a user