Add support for glTF transparent objects
Also added some Compositor uniforms.
This commit is contained in:
parent
2b9933c0b5
commit
6cea6b7fdf
@ -135,12 +135,12 @@ struct GLTFBuilder {
|
|||||||
group->addChild(geode);
|
group->addChild(geode);
|
||||||
|
|
||||||
SGPropertyNode_ptr effectRoot = new SGPropertyNode;
|
SGPropertyNode_ptr effectRoot = new SGPropertyNode;
|
||||||
|
// Material is OPAQUE by default, so inherit from model-pbr
|
||||||
makeChild(effectRoot, "inherits-from")->setStringValue("Effects/model-pbr");
|
makeChild(effectRoot, "inherits-from")->setStringValue("Effects/model-pbr");
|
||||||
if (primitive.material >= 0) {
|
if (primitive.material >= 0) {
|
||||||
// We have a material assigned to the primitive, add all the
|
// We have a material assigned to the primitive, add all the
|
||||||
// required material info as parameters to the Effect.
|
// required material info as parameters to the Effect.
|
||||||
makeMaterialParameters(makeChild(effectRoot, "parameters"),
|
makeMaterialParameters(effectRoot, model.materials[primitive.material]);
|
||||||
model.materials[primitive.material]);
|
|
||||||
}
|
}
|
||||||
Effect *effect = makeEffect(effectRoot, true, opts);
|
Effect *effect = makeEffect(effectRoot, true, opts);
|
||||||
if (effect)
|
if (effect)
|
||||||
@ -212,10 +212,24 @@ struct GLTFBuilder {
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool makeMaterialParameters(SGPropertyNode *params,
|
bool makeMaterialParameters(SGPropertyNode *effectRoot,
|
||||||
const tinygltf::Material &material) const {
|
const tinygltf::Material &material) const {
|
||||||
|
SGPropertyNode *params = makeChild(effectRoot, "parameters");
|
||||||
const tinygltf::PbrMetallicRoughness &pbr = material.pbrMetallicRoughness;
|
const tinygltf::PbrMetallicRoughness &pbr = material.pbrMetallicRoughness;
|
||||||
|
|
||||||
|
// Handle transparent modes
|
||||||
|
// We have a separate Effect for transparent objects, so inherit from
|
||||||
|
// that instead.
|
||||||
|
if (material.alphaMode == "MASK") {
|
||||||
|
effectRoot->setStringValue("inherits-from", "Effects/model-pbr-transparent");
|
||||||
|
makeChild(params, "blend")->setValue(0);
|
||||||
|
makeChild(params, "alpha-cutoff")->setValue(material.alphaCutoff);
|
||||||
|
} else if (material.alphaMode == "BLEND") {
|
||||||
|
effectRoot->setStringValue("inherits-from", "Effects/model-pbr-transparent");
|
||||||
|
makeChild(params, "blend")->setValue(1);
|
||||||
|
makeChild(params, "alpha-cutoff")->setValue(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
makeChild(params, "base-color-factor")->setValue(
|
makeChild(params, "base-color-factor")->setValue(
|
||||||
SGVec4d(pbr.baseColorFactor[0],
|
SGVec4d(pbr.baseColorFactor[0],
|
||||||
pbr.baseColorFactor[1],
|
pbr.baseColorFactor[1],
|
||||||
@ -228,21 +242,6 @@ struct GLTFBuilder {
|
|||||||
material.emissiveFactor[1],
|
material.emissiveFactor[1],
|
||||||
material.emissiveFactor[2]));
|
material.emissiveFactor[2]));
|
||||||
|
|
||||||
SGPropertyNode *blendNode = makeChild(params, "blend");
|
|
||||||
if (material.alphaMode == "OPAQUE") {
|
|
||||||
makeChild(blendNode, "active")->setValue(false);
|
|
||||||
makeChild(params, "rendering-hint")->setStringValue("opaque");
|
|
||||||
makeChild(params, "alpha-cutoff")->setValue(-1.0);
|
|
||||||
} else if (material.alphaMode == "MASK") {
|
|
||||||
makeChild(blendNode, "active")->setValue(false);
|
|
||||||
makeChild(params, "rendering-hint")->setStringValue("opaque");
|
|
||||||
makeChild(params, "alpha-cutoff")->setValue(material.alphaCutoff);
|
|
||||||
} else if (material.alphaMode == "BLEND") {
|
|
||||||
makeChild(blendNode, "active")->setValue(true);
|
|
||||||
makeChild(params, "rendering-hint")->setStringValue("transparent");
|
|
||||||
makeChild(params, "alpha-cutoff")->setValue(-1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cullFaceString;
|
std::string cullFaceString;
|
||||||
if (material.doubleSided) {
|
if (material.doubleSided) {
|
||||||
cullFaceString = "off";
|
cullFaceString = "off";
|
||||||
|
@ -135,7 +135,7 @@ Compositor::Compositor(osg::View *view,
|
|||||||
_gc(gc),
|
_gc(gc),
|
||||||
_viewport(viewport),
|
_viewport(viewport),
|
||||||
_uniforms{
|
_uniforms{
|
||||||
new osg::Uniform("fg_ViewportSize", osg::Vec2f()),
|
new osg::Uniform("fg_Viewport", osg::Vec4f()),
|
||||||
new osg::Uniform("fg_ViewMatrix", osg::Matrixf()),
|
new osg::Uniform("fg_ViewMatrix", osg::Matrixf()),
|
||||||
new osg::Uniform("fg_ViewMatrixInverse", osg::Matrixf()),
|
new osg::Uniform("fg_ViewMatrixInverse", osg::Matrixf()),
|
||||||
new osg::Uniform("fg_ProjectionMatrix", osg::Matrixf()),
|
new osg::Uniform("fg_ProjectionMatrix", osg::Matrixf()),
|
||||||
@ -146,10 +146,14 @@ Compositor::Compositor(osg::View *view,
|
|||||||
new osg::Uniform("fg_PrevProjectionMatrixInverse", osg::Matrixf()),
|
new osg::Uniform("fg_PrevProjectionMatrixInverse", osg::Matrixf()),
|
||||||
new osg::Uniform("fg_CameraPositionCart", osg::Vec3f()),
|
new osg::Uniform("fg_CameraPositionCart", osg::Vec3f()),
|
||||||
new osg::Uniform("fg_CameraPositionGeod", osg::Vec3f()),
|
new osg::Uniform("fg_CameraPositionGeod", osg::Vec3f()),
|
||||||
|
new osg::Uniform("fg_CameraDistanceToEarthCenter", 0.0f),
|
||||||
new osg::Uniform("fg_NearFar", osg::Vec2f()),
|
new osg::Uniform("fg_NearFar", osg::Vec2f()),
|
||||||
new osg::Uniform("fg_Planes", osg::Vec3f()),
|
new osg::Uniform("fg_Planes", osg::Vec3f()),
|
||||||
new osg::Uniform("fg_SunDirection", osg::Vec3f()),
|
new osg::Uniform("fg_SunDirection", osg::Vec3f()),
|
||||||
new osg::Uniform("fg_SunDirectionWorld", osg::Vec3f()),
|
new osg::Uniform("fg_SunDirectionWorld", osg::Vec3f()),
|
||||||
|
new osg::Uniform("fg_SunZenithCosTheta", 0.0f),
|
||||||
|
new osg::Uniform("fg_EarthRadius", 0.0f),
|
||||||
|
new osg::Uniform("fg_WorldUp", osg::Vec3f()),
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
_uniforms[SG_UNIFORM_SUN_DIRECTION_WORLD]->setUpdateCallback(
|
_uniforms[SG_UNIFORM_SUN_DIRECTION_WORLD]->setUpdateCallback(
|
||||||
@ -176,10 +180,16 @@ Compositor::update(const osg::Matrix &view_matrix,
|
|||||||
|
|
||||||
// Update uniforms
|
// Update uniforms
|
||||||
osg::Matrixd view_inverse = osg::Matrix::inverse(view_matrix);
|
osg::Matrixd view_inverse = osg::Matrix::inverse(view_matrix);
|
||||||
osg::Vec4d camera_pos = osg::Vec4(0.0, 0.0, 0.0, 1.0) * view_inverse;
|
osg::Vec4d camera_pos4 = osg::Vec4d(0.0, 0.0, 0.0, 1.0) * view_inverse;
|
||||||
|
osg::Vec3d camera_pos = osg::Vec3d(camera_pos4.x(),
|
||||||
|
camera_pos4.y(),
|
||||||
|
camera_pos4.z());
|
||||||
SGGeod camera_pos_geod = SGGeod::fromCart(
|
SGGeod camera_pos_geod = SGGeod::fromCart(
|
||||||
SGVec3d(camera_pos.x(), camera_pos.y(), camera_pos.z()));
|
SGVec3d(camera_pos.x(), camera_pos.y(), camera_pos.z()));
|
||||||
|
|
||||||
|
osg::Vec3d world_up = camera_pos;
|
||||||
|
world_up.normalize();
|
||||||
|
|
||||||
double left = 0.0, right = 0.0, bottom = 0.0, top = 0.0,
|
double left = 0.0, right = 0.0, bottom = 0.0, top = 0.0,
|
||||||
zNear = 0.0, zFar = 0.0;
|
zNear = 0.0, zFar = 0.0;
|
||||||
proj_matrix.getFrustum(left, right, bottom, top, zNear, zFar);
|
proj_matrix.getFrustum(left, right, bottom, top, zNear, zFar);
|
||||||
@ -204,8 +214,9 @@ Compositor::update(const osg::Matrix &view_matrix,
|
|||||||
for (int i = 0; i < SG_TOTAL_BUILTIN_UNIFORMS; ++i) {
|
for (int i = 0; i < SG_TOTAL_BUILTIN_UNIFORMS; ++i) {
|
||||||
osg::ref_ptr<osg::Uniform> u = _uniforms[i];
|
osg::ref_ptr<osg::Uniform> u = _uniforms[i];
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case SG_UNIFORM_VIEWPORT_SIZE:
|
case SG_UNIFORM_VIEWPORT:
|
||||||
u->set(osg::Vec2f(_viewport->width(), _viewport->height()));
|
u->set(osg::Vec4f(_viewport->x(), _viewport->y(),
|
||||||
|
_viewport->width(), _viewport->height()));
|
||||||
break;
|
break;
|
||||||
case SG_UNIFORM_VIEW_MATRIX:
|
case SG_UNIFORM_VIEW_MATRIX:
|
||||||
u->set(view_matrix);
|
u->set(view_matrix);
|
||||||
@ -220,13 +231,16 @@ Compositor::update(const osg::Matrix &view_matrix,
|
|||||||
u->set(osg::Matrix::inverse(proj_matrix));
|
u->set(osg::Matrix::inverse(proj_matrix));
|
||||||
break;
|
break;
|
||||||
case SG_UNIFORM_CAMERA_POSITION_CART:
|
case SG_UNIFORM_CAMERA_POSITION_CART:
|
||||||
u->set(osg::Vec3f(camera_pos.x(), camera_pos.y(), camera_pos.z()));
|
u->set(osg::Vec3f(camera_pos));
|
||||||
break;
|
break;
|
||||||
case SG_UNIFORM_CAMERA_POSITION_GEOD:
|
case SG_UNIFORM_CAMERA_POSITION_GEOD:
|
||||||
u->set(osg::Vec3f(camera_pos_geod.getLongitudeRad(),
|
u->set(osg::Vec3f(camera_pos_geod.getLongitudeRad(),
|
||||||
camera_pos_geod.getLatitudeRad(),
|
camera_pos_geod.getLatitudeRad(),
|
||||||
camera_pos_geod.getElevationM()));
|
camera_pos_geod.getElevationM()));
|
||||||
break;
|
break;
|
||||||
|
case SG_UNIFORM_CAMERA_DISTANCE_TO_EARTH_CENTER:
|
||||||
|
u->set(float(camera_pos.length()));
|
||||||
|
break;
|
||||||
case SG_UNIFORM_NEAR_FAR:
|
case SG_UNIFORM_NEAR_FAR:
|
||||||
u->set(osg::Vec2f(zNear, zFar));
|
u->set(osg::Vec2f(zNear, zFar));
|
||||||
break;
|
break;
|
||||||
@ -236,6 +250,15 @@ Compositor::update(const osg::Matrix &view_matrix,
|
|||||||
case SG_UNIFORM_SUN_DIRECTION:
|
case SG_UNIFORM_SUN_DIRECTION:
|
||||||
u->set(osg::Vec3f(sun_dir_view.x(), sun_dir_view.y(), sun_dir_view.z()));
|
u->set(osg::Vec3f(sun_dir_view.x(), sun_dir_view.y(), sun_dir_view.z()));
|
||||||
break;
|
break;
|
||||||
|
case SG_UNIFORM_SUN_ZENITH_COSTHETA:
|
||||||
|
u->set(float(sun_dir_world * world_up));
|
||||||
|
break;
|
||||||
|
case SG_UNIFORM_EARTH_RADIUS:
|
||||||
|
u->set(float(camera_pos.length() - camera_pos_geod.getElevationM()));
|
||||||
|
break;
|
||||||
|
case SG_UNIFORM_WORLD_UP:
|
||||||
|
u->set(osg::Vec3f(world_up));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Unknown uniform
|
// Unknown uniform
|
||||||
break;
|
break;
|
||||||
|
@ -46,7 +46,7 @@ namespace compositor {
|
|||||||
class Compositor {
|
class Compositor {
|
||||||
public:
|
public:
|
||||||
enum BuiltinUniform {
|
enum BuiltinUniform {
|
||||||
SG_UNIFORM_VIEWPORT_SIZE = 0,
|
SG_UNIFORM_VIEWPORT = 0,
|
||||||
SG_UNIFORM_VIEW_MATRIX,
|
SG_UNIFORM_VIEW_MATRIX,
|
||||||
SG_UNIFORM_VIEW_MATRIX_INV,
|
SG_UNIFORM_VIEW_MATRIX_INV,
|
||||||
SG_UNIFORM_PROJECTION_MATRIX,
|
SG_UNIFORM_PROJECTION_MATRIX,
|
||||||
@ -57,10 +57,14 @@ public:
|
|||||||
SG_UNIFORM_PREV_PROJECTION_MATRIX_INV,
|
SG_UNIFORM_PREV_PROJECTION_MATRIX_INV,
|
||||||
SG_UNIFORM_CAMERA_POSITION_CART,
|
SG_UNIFORM_CAMERA_POSITION_CART,
|
||||||
SG_UNIFORM_CAMERA_POSITION_GEOD,
|
SG_UNIFORM_CAMERA_POSITION_GEOD,
|
||||||
|
SG_UNIFORM_CAMERA_DISTANCE_TO_EARTH_CENTER,
|
||||||
SG_UNIFORM_NEAR_FAR,
|
SG_UNIFORM_NEAR_FAR,
|
||||||
SG_UNIFORM_PLANES,
|
SG_UNIFORM_PLANES,
|
||||||
SG_UNIFORM_SUN_DIRECTION,
|
SG_UNIFORM_SUN_DIRECTION,
|
||||||
SG_UNIFORM_SUN_DIRECTION_WORLD,
|
SG_UNIFORM_SUN_DIRECTION_WORLD,
|
||||||
|
SG_UNIFORM_SUN_ZENITH_COSTHETA,
|
||||||
|
SG_UNIFORM_EARTH_RADIUS,
|
||||||
|
SG_UNIFORM_WORLD_UP,
|
||||||
SG_TOTAL_BUILTIN_UNIFORMS
|
SG_TOTAL_BUILTIN_UNIFORMS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -765,8 +765,15 @@ public:
|
|||||||
|
|
||||||
osg::StateSet *ss = camera->getOrCreateStateSet();
|
osg::StateSet *ss = camera->getOrCreateStateSet();
|
||||||
auto &uniforms = compositor->getBuiltinUniforms();
|
auto &uniforms = compositor->getBuiltinUniforms();
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_VIEWPORT]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_CAMERA_POSITION_CART]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_CAMERA_POSITION_GEOD]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_CAMERA_DISTANCE_TO_EARTH_CENTER]);
|
||||||
ss->addUniform(uniforms[Compositor::SG_UNIFORM_SUN_DIRECTION]);
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_SUN_DIRECTION]);
|
||||||
ss->addUniform(uniforms[Compositor::SG_UNIFORM_SUN_DIRECTION_WORLD]);
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_SUN_DIRECTION_WORLD]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_SUN_ZENITH_COSTHETA]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_EARTH_RADIUS]);
|
||||||
|
ss->addUniform(uniforms[Compositor::SG_UNIFORM_WORLD_UP]);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Uniform> clustered_shading_enabled =
|
osg::ref_ptr<osg::Uniform> clustered_shading_enabled =
|
||||||
new osg::Uniform("fg_ClusteredEnabled", clustered ? true : false);
|
new osg::Uniform("fg_ClusteredEnabled", clustered ? true : false);
|
||||||
|
Loading…
Reference in New Issue
Block a user