How to get skins/textures from a TurboSquid model to display in my Babylon scene

blender

#1

I’m a front-end web dev and complete novice at 3D platforms. I’m trying to create a simple proof of concept to show my management that we can use models from third parties such as TurboSquid to create an interactive web interface that allows customers to change the colors of some of the model surfaces. I’ve been able to download a free car model from TS (free duesen bayern mystar 190 3d model) and export it to Blender 2.79 as a Babylon.JS file. I’m succeeding in importing that model in Babylon and changing the color for part of the model, at least, with code like this:

let material = task.loadedMeshes[0].material = new BABYLON.StandardMaterial(‘mat’, scene);
material.emissiveColor = BABYLON.Color3.Red();

While I realize that I need to get at least some basic Babylon.JS skills under my belt (and am spending this
Sunday afternoon getting started), the sooner that I can show my team a decent demo, the sooner that I’ll be able to devote some work hours to it. I had the impression from the TurboSquid listing that this model came with several naturalistic skins (textures? materials?). I was hoping that I could get a quick win by adding code to just change the color of some of those surfaces.

At this point, I’m just hoping that someone can tell me if there is a step that I missed which is preventing those skins from displaying. I’m wondering if maybe it’s just that the file format that I imported into Blender (OBJ) doesn’t support that, or if Blender just can’t export them to the Babylon file format.

This is actually the first time that I’ve posted a question to a forum. I have read that the Babylon community is amazing. I’m amazed that a platform as powerful and as supported as BabylonJS is open source. I applaud this amazing thing that you all have built, and I thank you in advance for any guidance that you can give!


#2

Heya, Preston!

What kind of skins did you say came with the model?

It should have just come with some extra PNGs or TGAs or the like that you can switch over to, which you should be able to use similarly to your first line.

For example: material.diffuseTexture = “textures/car_Diffuse2.png”;

However, I might not understand your situation fully. Let us know how that works out for you, and if this helps, here is the wiki on materials. You can find the section on Textures half way down:

https://doc.babylonjs.com/babylon101/materials


#3

Thank you so much for that incredibly fast response, this community really is amazing!

I don’t see any image files of any kind in the zipped files for the OBJ format (which, it appears, is the only format that this model comes in and which is supported by Blender). I took a look at the JSON that I exported from Blender, and see that the “materials” array is empty (I paste a few other relevant parts of the JSON below). I’m wondering if this is just a limitation of the OBJ format of the model, which TurboSquid calls an exchange format (not original). Is there a Blender export setting for textures that I might have missed?

In the meantime, I’ve started learning a few BJS basics, and am really enjoying the platform! I may be able to manually add the textures that I want, but last night I hit a new snag. I started learning about shadow generators so that I can have the car cast a shadow on the ground that I added. I have giant array of meshes that make up the car. I’m loading them into my scene with this code:

var assetsManager = new BABYLON.AssetsManager(scene);
var meshTask = assetsManager.addMeshTask(“car task”, “”, “scenes/”, “car.babylon”);

        meshTask.onSuccess = function (task) {
            task.loadedMeshes[0].position = BABYLON.Vector3.Zero();
        }	

How do I group all the mesh and base a shadow generator on them? Or is that the right idea at all? I would guess that the performance for that would be awful. Do I need to create a single transparent mesh that will act as a proxy for the car and attach the shadow generator to that? I do notice in my shadowGenerators array is also empty.

Again, thank you very much for your help and expertise! I can’t wait to know enough to give back to the community myself.

{“producer”:{“name”:“Blender”,“version”:“2.79 (sub 0)”,“exporter_version”:“5.6.4”,“file”:“car.babylon”},
“autoClear”:true,“clearColor”:[0.0509,0.0509,0.0509],“ambientColor”:[0,0,0],“gravity”:[0,-9.81,0],
“materials”:[],
“multiMaterials”:[],
“skeletons”:[],
,“subMeshes”:[{“materialIndex”:0,“verticesStart”:0,“verticesCount”:1848,“indexStart”:0,“indexCount”:10560}]
,“instances”:[]}
],

“meshes”:[{“name”:“Z3_glass4”,“id”:“Z3_glass4”,“billboardMode”:0,“position”:[0,0,0],“rotation”:[-1.5708,0,0],“scaling”:[1,1,1],“isVisible”:true,“freezeWorldMatrix”:false,“isEnabled”:true,“checkCollisions”:false,“receiveShadows”:false,“pickable”:true,“tags”:""
,“positions”:[4.3198,24.4756,40.4464, …

“morphTargetManagers”:[],
“cameras”:[{“name”:“Camera”,“id”:“Camera”,“position”:[7.4811,5.3437,-6.5076],“rotation”:[0.4615,-0.8149,0],“fov”:0.8576,“minZ”:0.1,“maxZ”:100,“speed”:1,“inertia”:0.9,“checkCollisions”:false,“applyGravity”:false,“ellipsoid”:[0.2,0.9,0.2],“cameraRigMode”:0,“interaxial_distance”:0.0637,“type”:“UniversalCamera”}],“activeCamera”:“Camera”,
“lights”:[{“name”:“Lamp”,“id”:“Lamp”,“type”:0,“position”:[4.0762,5.9039,1.0055],“intensity”:1,“diffuse”:[1,1,1],“specular”:[1,1,1]}],
“shadowGenerators”:[]
}


#4

Actually on the contrary, it should be just fine to do it that way! Babylonjs’ shadow generator calculates the shadowmap size based on the distance of the meshes from each other, so having one mesh like your car example here made up of a bunch of meshes doesn’t matter at all. Since the pieces are all so close to each other, making up just the one car, then the shadow cast ends up efficiently taking up the shadow map as expected with no perceptible loss in shadow resolution.

Here’s what your new meshTask would look like, assuming you already have a light and a shadow generator defined before this function:

meshTask.onSuccess = function (task) {
    task.loadedMeshes[0].position = BABYLON.Vector3.Zero(); //I believe the default position is already 0
    for (var i = 1; i < task.loadedMeshes.length; i++)
    {
        shadowGenerator.addShadowCaster(task.loadedMeshes[i]);
    }
}

I skipped over loadedMeshes[0] for the shadows since as far as I know that’s just the transform node for the group of meshes.

As for your question about OBJs, while an OBJ does have a .mat file, usually actual image textures are needed in addition to the material file since the mat file just reads what goes where.

I read through the specs of that free model and it does say it has Vray materials included, which would be procedural and don’t require image textures, but I think these are only usable in 3ds Max. At best the OBJ mat file would be able to get the colors right if even that, but I think you may just have to redefine the materials in your meshTask.onSuccess. Since the car already has pretty basic materials I think this would be the easiest option.

Alternatively, my favorite way of working is to import the mesh into the beta Blender 2.8 and defining the material properties using the Principled Shader in Eevee and then exporting to a GLB 2.0 file, which Babylonjs can read the PBR material information from. That way you don’t have a bunch of material code taking up a large amount of space in your import functions and all of your image textures, if any are used, are compressed into one easy to use file.


#5

TurboSquid StemCell and BabylonJS both support glTF. If this new workflow in TurboSquid works for your scenario, in theory, you can convert TurboSquid models straight to glTF and then into BabylonJS without having to worry about tools in the middle.