Jump to content

Can't get Multi Materials to work with Dynamic Textures


dbawel
 Share

Recommended Posts

Hello,

 

I have a scene which allows you to paint on 3D objects.  In addition to painting on 3D objects, I need to add a function in which you can load an existing texture, and paint on the already textured object directly.  In the link below, you'll see a sphere which you can paint directly onto - if you want to change the brush color, click the color icons on the right side of the interface.  The rest of the interface is not yet connected to any functions.  

 

You'll also see a plane in the scene which is rendered white - although I have applied a MultiMaterial containing 3 materials onto this plane object; one which has a color value of white (1,1,1), a second material which has a texture applied to it, and a 3rd material which has the same dynamic texture applied to the sphere which allows you to paint on the sphere.  I'm pushing all 3 materials into a single MultiMaterial "var multimat", but only the first material with the color value of (1,1,1) is rendered.  The dynamic material is functioning on the plane, as you can paint on the plane directly (with no result on the plane) since it shares the same dynamic material as the sphere, and you'll see the paint appear on the sphere when painting on the plane.

 

The link to this scene is:

http://www.qedsoft.com/DEMOS2014/creative_drawing_v1/index.html

 

 

Below is a portion of the script which is used for the scene elements which are having issues.  The code below is not useful for testing or building a playground scene, as it is a small portion of just one java script to define the app.  The code containing the multi-material for the plane is placed between two long lines of "//" remarks which are repeated numerous times to make the problematic code easier to locate in the script:

 

 
 
function init3d (scene, canvas) {
    //var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);
   // var light = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(-17.6, 18.8, -49.9), scene);
 
    //camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -15), scene);
    //camera.setTarget(BABYLON.Vector3.Zero());    
 
    var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, 1.55, -10, BABYLON.Vector3.Zero(), scene);
 
    //camera.setPosition(new BABYLON.Vector3(-15, 3, 0));
    //camera.attachControl(canvas, true);
 
    // Skybox
    var skybox = BABYLON.Mesh.CreateBox("skyBox", 200.0, scene);
    var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
    skyboxMaterial.backFaceCulling = false;
    skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("./skybox/TropicalSunnyDay", scene);
    skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
    skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
    skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
    skybox.material = skyboxMaterial;
    skybox.layerMask = 1;
 
 
    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
    light.intensity = 0.7;
 
    // light for video screen
    var light1 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 80, -80), scene);
 
///////////////////////////////////////////////////////////////////////////////////////////////////////
 
var groundTexture = new BABYLON.DynamicTexture("dynamic texture", 512, scene, true);
 
var dynamicMaterial = new BABYLON.StandardMaterial('mat', scene);
dynamicMaterial.diffuseTexture = groundTexture;
dynamicMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
dynamicMaterial.backFaceCulling = false;
 
    // Create sphere
    var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 5, scene);
    sphere.material = dynamicMaterial;
    sphere.rotation.x = -Math.PI / 2;
 
    // Move the sphere upward 1/2 its height
    sphere.position.y = 1;
 
    // Create ground
    var ground = BABYLON.Mesh.CreateGround("ground1", 10, 10, 2, scene);
    ground.position = new BABYLON.Vector3(-200,0,0);
    ground.material = dynamicMaterial;
    ground.visibility = 0
 
 
    var material0 = new BABYLON.StandardMaterial("mat0", scene);
    material0.diffuseColor = new BABYLON.Color3(1, 1, 1);
 
    var material1 = new BABYLON.StandardMaterial("mat1", scene);
    material1.diffuseColor = new BABYLON.Color3(0, 0, 1);
    material1.diffuseTexture = new BABYLON.Texture("./textures/video_screen_512.png", scene);
 
    var material2 = new BABYLON.StandardMaterial("mat2", scene);
    material2.diffuseTexture = groundTexture;
 
    var multimat = new BABYLON.MultiMaterial("multi", scene);
    multimat.subMaterials.push(material0);
    multimat.subMaterials.push(material1);
    multimat.subMaterials.push(material2);
 
 
    //Creation of a video plane
    var plane = BABYLON.Mesh.CreatePlane("plane", "10", scene);
    plane.position = new BABYLON.Vector3(0,0.1,0);
    plane.scaling = new BABYLON.Vector3(.95,0.5,1);
    plane.visibility = 1;
 
    plane.material = multimat;
 
///////////////////////////////////////////////////////////////////////////////////////////////////////
 
var clearColor = "#555555";
var font = "bold 70px Segoe UI";
var invertY = true;
var text = "test";
var color = "white"
var x = 10;
var y = 80;
 
var context = groundTexture._context;
var size = groundTexture.getSize();
 
    if (clearColor) {
context.fillStyle = clearColor;
context.fillRect(0, 0, size.width, size.height);
}
     
groundTexture.update(invertY);
 
 
 
 
If anyone can help me with the correct code to get the multi-material to function correctly where I can display the "video_screen_512.png" texture and also paint directly on the plane, it would be much appriciated.  
 
FYI - If I remove the material which is set as "var material0" from the script and from the MultiMaterial (this is the material which has the color value of (1,1,1)), then the material which is set as "var material1" containing the "video_screen_512.png" texture appears correctly on the plane.
In addition, if I switch the order of the materials I'm pushing to the MultiMaterial where material2 is pushed before material1, then only the dynamic texture is displayed, and I can paint directly onto the plane. ( "var material1" containing the "video_screen_512.png" texture is not displayed.) An example of this code is below:
 

    var multimat = new BABYLON.MultiMaterial("multi", scene);
    multimat.subMaterials.push(material2);
    multimat.subMaterials.push(material1);
 
Thanks,
 
DB
Link to comment
Share on other sites

I did a quick text search for 'submesh' in this script, & did not find any being created.  I am only going on my Blender exporter work, but there needs to be a sub mesh for each material in the multi-material.  There is one sub mesh of the entire mesh created automatically.  If there are no sub meshes added, which specify the materialIndex, verticesStart, indexStart, verticesCount, indexCount, then only the first one is probably going to be used.

Link to comment
Share on other sites

@Deltakosh - Posting this large section of the script is not what I would have preferred either, however I included the entire script in the post, as the problem might very well have been in the functions with which I'm using dynamic textures to draw on objects -  along with the addition of the bGUI extension for the interface - which I cannot reproduce in the playground, along with the dozens of other textures used for the interface. Otherwise, I would much rather submit a playground scene scaled down to expose the problem specifically.  It's just that this scene is a bit too compex for the playground to reproduce all of the associated factors which might be contributing to the problem.  However, with the advice JCP provided, I'll edit the original post now, and remove most of the script which due to JCPalmers response identifies that the issue is definately due to my not defining submeshes for the MultiMaterials to be attached.

 

@JCPalmer - I'm not very familiar with MultiMaterials - and specifically their use with dynamic textures.  But your advice is very helpful, as you are correct; this is the reason why I'm receiving the rendering result which is only rendering the first material pushed on the plane - as MultiMaterials do require submeshes to render, otherwise only the first material pushed to the MultiMaterial will be rendered.  With this info and recalling that submeshes are required to define for MultiMaterials, I need to test if an entire mesh can be defined and redifined as a submesh to be able to apply several materials to the entire object, and not only a defined section (submesh) of the object for each material.  Thank you for bringing this info to my attention, as it is definately the root of the problem.

Link to comment
Share on other sites

Hi DK,

 

The link in the beginning of the post is a running example, with all of the code in the original post - excluding the .html and .css files, as well as the extensions and the tons of textures as you can see just in the interface.  This is another reason why it wasn't practical to create a playgound scene initially, as there are so many required assets such as textures that it would be a huge undertaking.  I've since then edited out much of the script, and left only the section addressing the materials just for reference.

 

I don't have a solution to what I'm attempting, however, I will most likely mark this solved by JCPalmer as the problem is definately that I don't have submeshes defined on my object.  But I'll leave it unsolved for the time being in case someone might have enough experience specific to my scene to offer up an actual working solution.  If there is that person out there who has the specific experience which might bring a solution, they can open the scripts in the javascript console. But I also hope to find a solution myself this evening with the relaization that the problem is due to submeshes.  So there's no need to try and build some kind of replication now, as I basically know what to do.  I wouldn't even know where to begin to attempt to replicate in the playground anyway.

 

But thanks for all of your attention to this.  I hope to have the multi-user real-time version of this fully funtioning and posted on the forum by Thursday - finally -  if all goes as planned now.

 

Cheers,

 

DB

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...