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);
|
||||
|
||||
SGPropertyNode_ptr effectRoot = new SGPropertyNode;
|
||||
// Material is OPAQUE by default, so inherit from model-pbr
|
||||
makeChild(effectRoot, "inherits-from")->setStringValue("Effects/model-pbr");
|
||||
if (primitive.material >= 0) {
|
||||
// We have a material assigned to the primitive, add all the
|
||||
// required material info as parameters to the Effect.
|
||||
makeMaterialParameters(makeChild(effectRoot, "parameters"),
|
||||
model.materials[primitive.material]);
|
||||
makeMaterialParameters(effectRoot, model.materials[primitive.material]);
|
||||
}
|
||||
Effect *effect = makeEffect(effectRoot, true, opts);
|
||||
if (effect)
|
||||
@ -212,10 +212,24 @@ struct GLTFBuilder {
|
||||
return group;
|
||||
}
|
||||
|
||||
bool makeMaterialParameters(SGPropertyNode *params,
|
||||
bool makeMaterialParameters(SGPropertyNode *effectRoot,
|
||||
const tinygltf::Material &material) const {
|
||||
SGPropertyNode *params = makeChild(effectRoot, "parameters");
|
||||
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(
|
||||
SGVec4d(pbr.baseColorFactor[0],
|
||||
pbr.baseColorFactor[1],
|
||||
@ -228,21 +242,6 @@ struct GLTFBuilder {
|
||||
material.emissiveFactor[1],
|
||||
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;
|
||||
if (material.doubleSided) {
|
||||
cullFaceString = "off";
|
||||
|
@ -135,7 +135,7 @@ Compositor::Compositor(osg::View *view,
|
||||
_gc(gc),
|
||||
_viewport(viewport),
|
||||
_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_ViewMatrixInverse", 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_CameraPositionCart", 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_Planes", osg::Vec3f()),
|
||||
new osg::Uniform("fg_SunDirection", 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(
|
||||
@ -176,10 +180,16 @@ Compositor::update(const osg::Matrix &view_matrix,
|
||||
|
||||
// Update uniforms
|
||||
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(
|
||||
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,
|
||||
zNear = 0.0, zFar = 0.0;
|
||||
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) {
|
||||
osg::ref_ptr<osg::Uniform> u = _uniforms[i];
|
||||
switch (i) {
|
||||
case SG_UNIFORM_VIEWPORT_SIZE:
|
||||
u->set(osg::Vec2f(_viewport->width(), _viewport->height()));
|
||||
case SG_UNIFORM_VIEWPORT:
|
||||
u->set(osg::Vec4f(_viewport->x(), _viewport->y(),
|
||||
_viewport->width(), _viewport->height()));
|
||||
break;
|
||||
case SG_UNIFORM_VIEW_MATRIX:
|
||||
u->set(view_matrix);
|
||||
@ -220,13 +231,16 @@ Compositor::update(const osg::Matrix &view_matrix,
|
||||
u->set(osg::Matrix::inverse(proj_matrix));
|
||||
break;
|
||||
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;
|
||||
case SG_UNIFORM_CAMERA_POSITION_GEOD:
|
||||
u->set(osg::Vec3f(camera_pos_geod.getLongitudeRad(),
|
||||
camera_pos_geod.getLatitudeRad(),
|
||||
camera_pos_geod.getElevationM()));
|
||||
break;
|
||||
case SG_UNIFORM_CAMERA_DISTANCE_TO_EARTH_CENTER:
|
||||
u->set(float(camera_pos.length()));
|
||||
break;
|
||||
case SG_UNIFORM_NEAR_FAR:
|
||||
u->set(osg::Vec2f(zNear, zFar));
|
||||
break;
|
||||
@ -236,6 +250,15 @@ Compositor::update(const osg::Matrix &view_matrix,
|
||||
case SG_UNIFORM_SUN_DIRECTION:
|
||||
u->set(osg::Vec3f(sun_dir_view.x(), sun_dir_view.y(), sun_dir_view.z()));
|
||||
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:
|
||||
// Unknown uniform
|
||||
break;
|
||||
|
@ -46,7 +46,7 @@ namespace compositor {
|
||||
class Compositor {
|
||||
public:
|
||||
enum BuiltinUniform {
|
||||
SG_UNIFORM_VIEWPORT_SIZE = 0,
|
||||
SG_UNIFORM_VIEWPORT = 0,
|
||||
SG_UNIFORM_VIEW_MATRIX,
|
||||
SG_UNIFORM_VIEW_MATRIX_INV,
|
||||
SG_UNIFORM_PROJECTION_MATRIX,
|
||||
@ -57,10 +57,14 @@ public:
|
||||
SG_UNIFORM_PREV_PROJECTION_MATRIX_INV,
|
||||
SG_UNIFORM_CAMERA_POSITION_CART,
|
||||
SG_UNIFORM_CAMERA_POSITION_GEOD,
|
||||
SG_UNIFORM_CAMERA_DISTANCE_TO_EARTH_CENTER,
|
||||
SG_UNIFORM_NEAR_FAR,
|
||||
SG_UNIFORM_PLANES,
|
||||
SG_UNIFORM_SUN_DIRECTION,
|
||||
SG_UNIFORM_SUN_DIRECTION_WORLD,
|
||||
SG_UNIFORM_SUN_ZENITH_COSTHETA,
|
||||
SG_UNIFORM_EARTH_RADIUS,
|
||||
SG_UNIFORM_WORLD_UP,
|
||||
SG_TOTAL_BUILTIN_UNIFORMS
|
||||
};
|
||||
|
||||
|
@ -765,8 +765,15 @@ public:
|
||||
|
||||
osg::StateSet *ss = camera->getOrCreateStateSet();
|
||||
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_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 =
|
||||
new osg::Uniform("fg_ClusteredEnabled", clustered ? true : false);
|
||||
|
Loading…
Reference in New Issue
Block a user