Rendering differences between PC player and engine-only

As far as I know, if you have a scene in the editor, when you play that scene using the engine only, it should look the same, assuming you have re-created the same camera, lights and objects and you use the same scene settings like exposure and gamma-correction.

But I have a simple scene that renders quite differently using the engine only. Other than the camera, I just have one big globe and six identical lights. The lights are identical except for the positioning and rotation, I mean. In trying to achieve an even lighting effect across the globe, I positioned each light to be 10 units away in just the arrangement you would expect: one above, one below, one to the right, one to the left, one back and one front. In the editor, I have chosen the “2.2” setting for gamma correction. From experimentation, I believe this corresponds to the GAMMA_SRGBHDR constant that you use in engine-only code. At least this gives me the closest match between the two renderings.

In the editor, as in the player that it launches, the globe is very evenly lit. But not so when using just the engine. Any ideas? The first two images show the Africa side of the globe and the top of the globe (from the editor/player. The second show the same two views of the globe, engine-only.

Without seeing the project and engine code, it’s going to hard to really tell.

My first thoughts is is it a material setup issue where the engine only material looks shiner than the Editor.

The lights look brighter in the engine only example too.

That’s interesting, because there’s nothing in the code that refers to the materials. But there is the unofficial use of recreatePhysicalShapes() on each mesh on the globe. I don’t know if that might change anything about the material setup, but it is the only unusual thing in the code, I think.

The other value for gamma_correction (GAMMA_SRGB) produces even brighter looking lights.

materials seem different to me … one is specular / metalic, the other not at all.
Do you have the planet as an fbx, import it to glb and then use glb in the engine only project? Or is it just a sphere, and you add textures on to it (using a material?).

1 Like

I think the Editor has different defaults for the standard material when created.

OK, I was wrong about the materials. Since I’m importing the model (which started out as FBX and was converted to GLB) and then decomposing it into separate entities (for mouse-picking), I do have to copy the materials from the original meshes to the new ones. The colors are coming out correctly so it made me think the materials were properly copied over. But maybe the editor can find these materials and the engine-only code can’t?

Anyway, this code runs and then the original entity with all the meshes in it is removed from app.root.

      var meshes = this.entity.model.meshInstances;

      var len = meshes.length;

      for (var i = 0;  i < len; i++) {

          var collisionMode = false;

           var meshInstance = meshes[i];

           var name = meshInstance.node.name;

           var newname = "";
           
           //Check and see if this one is a 'cap'
           if (name.substr( name.length - 4, 4) == "_cap") {
               newname = name.substr(0, name.length - 4);
               collisionMode = true;
           }

           // --- create a blank entity
          var entity = new pc.Entity();

            // --- create a blank model
           var model = new pc.Model();
           node = new pc.GraphNode();
           model.graph = node;

           //we need a material to create the mesh, then we'll replace it with the correct one below
           var material = new pc.StandardMaterial();

           //create new meshInstance with mesh property
           var newMeshInstance = new pc.MeshInstance(meshInstance.mesh, material, node);

           model.meshInstances.push(newMeshInstance);

           //Add the newly created model to the entity
           entity.addComponent("model", {
               castShadows: true,
               receiveShadows: true,
           });
           entity.model.model = model;

           //Only create mesh colliders for the 'cap' objects
           if (collisionMode) {

               //Add the collision component, using the model we generated as the mesh
             entity.addComponent('collision', {
                     type: 'mesh'
             });

             entity.collision.data.model = model;
             entity.collision.system.recreatePhysicalShapes(entity.collision);
           }
           
           //Add the material
           for (var j = 0; j < entity.model.meshInstances.length; j++) {
             entity.model.meshInstances[j].material =  meshInstance.material;
          }

           //position and rotate the entity and add it to the app
           var pos = meshInstance.node.getPosition();
           pos.scale(100);
           entity.setPosition(pos);

           entity.setRotation( meshInstance.node.getRotation() );

           this.app.root.addChild(entity);

        }

With the engine only code, how are you loading the model and what is the directory structure of the model, materials and textures?

It would be great if an example can be provided of just the Earth model loading with engine only as it’s a bit difficult to guess what might not be happening :sweat_smile:

I am importing the model as a GLB file and expecting that all the materials and textures are embedded in that file and available, which is maybe a bad assumption. Anyway, here’s how the model is loaded:

    var url = "https://storage.googleapis.com/hearmynamefiles/gp/Globe4.glb";
          app.assets.loadFromUrl(url, "container", function (err, asset) {

              //create and add lights and camera (code omitted)

              globe = new pc.Entity();
              globe.addComponent("model", {
                name: "globe",
                  type: "asset",
                  asset: asset.resource.model,
                  castShadows: true,
              });

              // Add the new Entities to the hierarchy
              app.root.addChild(globe);

              //this is where the decompose code posted above runs
              _decomposeEntity(vueApp);
              globe.addComponent("script");
              globe.script.create("decomposeEntity");

             app.root.removeChild(globe);
}

if you import fbx to glb using playcanvas edior, then the textures and materials are stored separately in the editor as separate assets and not in the glb I believe.

1 Like

This is what the planet looks like in Editor when loading the GLB directly: https://playcanvas.com/editor/scene/1132049