Transparency alpha render issues

Damn, thanks for the help. The batch group was unfortunate, I never noticed it.

The look I’m going for is achievable with Alpha for blendMode and then playing with the emissive color. This all works and looks like in Babylon now, great!

Btw, it doesn’t seem to matter that Tint is ticked or not for the emissive color to apply. I guess that’s not intended?

1 Like

I believe tint is only needed to be ticked if there is texture for the map. @mvaligursky would be able to explain it better here :sweat_smile:

I believe you’re correct.

1 Like

Ah yeah makes sense… thanks again!

Hey again.

I’m now using the MeshOpt glb version of my model and some sorting issues returned. Maybe you could take a look at it again in my project? Is there something I can do about it? It isn’t that noticable.

Are you changing/updating the layers in the meshes after you add the GLB models to the scene so that the outer shell is rendered last?

Not yet, as the fbx imported mesh in the editor does not need that.

I don’t understand how you change the layer via code. When you access the model component of the runtime loaded .glb you can’t differentiate between the single meshInstances. When I tried to set _layer on the shell meshInstance it had no effect.

Yes, it’s a bit complicated with the legacy model component. You will have to use the Layer class methods to add and remove mesh instances (remove it from the current layer, add it to the new one):

https://developer.playcanvas.com/api/pc.Layer.html#addMeshInstances

With the newer render component I think it would be easier.

I’d gladly use render component, but that doesn’t work with glbs loaded at runtime?

Ok I did it like this

this.app.scene.layers.getLayerByName("World").removeMeshInstances([meshInstances[0]]);
this.app.scene.layers.getLayerByName("TransparentLayer").addMeshInstances([meshInstances[0]]);

and it did help. When the shell is rendered later some overlapping disappears but not all.
The real question is, how to automate/script this when I have like 20 glbs that are going to be loaded at runtime and all have to be set up like this.

I think it works, check this forum post it links to an engine example:

That’s a good question, not sure how to best approach this.

If you need to pick certain mesh instances and do that you can run a for loop based on some logic e.g. node name.

maybe you need to ‘sort’ those mesh instance based on their distance from the center of the whole object? Kind of rendering it from inside out.

1 Like

can I do this then:


self.app.assets.loadFromUrlAndFilename(self.url3, null, "container", function (err, asset3) {

       

        self.entity.addComponent('model', {
            asset: asset3.resource.model
        });

        self.app.scene.layers.getLayerByName("World").addMeshInstances(asset3.resource.model);
    });

{I want to set refraction on externaly loaded GLB model [as in PlayCanvas 3D HTML5 Game Engine]}

You can use entity.findComponents to get all render components under a parent entity and change the layers there.

~~eg https://playcanvas.com/editor/scene/1019167~~

Correct link: https://playcanvas.com/project/871826/overview/change-render-component-layers

LoadGlb.attributes.add('glbAsset', { type: 'asset', assetType: 'binary'});
LoadGlb.attributes.add('layerNames', { type: 'string', array: true});

// initialize code called once per entity
LoadGlb.prototype.initialize = function() {
    var self = this;
    utils.loadGlbContainerFromAsset(this.glbAsset, null, this.glbAsset.name, function (err, asset) {
        /** @type {pc.Entity} */
        var renderRootEntity = asset.resource.instantiateRenderEntity();
        self.entity.addChild(renderRootEntity);

        // Get all the render components that have been created in the hierarchy 
        /** @type {pc.RenderComponent[]} */
        var renders = renderRootEntity.findComponents('render');
        var layerIds = [];
        var i;
        // Get the list of layer ids
        for (i = 0; i < self.layerNames.length; ++i) {
            var layer = self.app.scene.layers.getLayerByName(self.layerNames[i]);
            if (layer !== null) {
                layerIds.push(layer.id);
            }
        }

        for (i = 0; i < renders.length; ++i) {
            renders[i].layers = layerIds;
        }

        // If you need a list of materials to edit, you can use:
        // `asset.resource.materials` for an array of material assets
    });
};

The other thing you may need to do is disable depth write on the materials that are created when loading the GLB which I believe you did in the earlier test project?

1 Like

Ok, sound reasonable - but I don’t get a length at layerNames.length … looks empty

  • and thereby a cannot allocate the model to the World Layer
    PS: yes, I remember vaguely that I gave up the last time - but I dont think I tried the layer approach then

What do you mean by this? It is possible.

Have you parsed attributes on the script and added layer names into it?

(I’ve realised I posted the wrong link to the project. Here’s the correct one: PlayCanvas 3D HTML5 Game Engine)

I’m using MeshOpt glbs though. The load functions for them are done with model components. Simply exchanging them to render components doesn’t work.

Yes, in the meantime I found out - (here with out of context names:

meshKorrektOrder.layer =1;
console.log("Get LayID: " + meshKorrektOrder.layer);

)

But the problem remains regarding the externally loaded model

  • I wait for 20 frames to secure any mish-mash, but the model/entity will not output a layer ID:
    [here is the top of the refraction postUPdate]:
Refraction.prototype.postUpdate = function(dt) {

    if(this.app.root.findByName("RightHandUrHook_SwarowskiEx").script.lexg3.fr >20){

    if (this.firstRender) {

        this.firstRender = false;

       

        var self = this;

        var device = this.app.graphicsDevice;

       

        if (! this.layerRefraction) {

            console.log('Refraction: no "Refraction" layer found.');

            return;

        }

       

        // create render target

        this.resize();

       

        // for each entity marked as refract

        var entities = self.app.root.findByGuid("927307b2-ee29-483a-a62f-d0e70f77907e");

        console.log("LAYER1: "+ entities.layer); // this outputs undefined

That’s okay. Change the code I posted to look for model components instead.