We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Apply different material / texture to different sides of a mesh

I have a mesh which has been loaded from an external resource, and I need to be able to apply 2 different materials / textures to 2 different “surfaces” on the mesh. So picture a cube mesh, where the 2 triangles representing one face of the cube displays picture A, and another face displays picture B.

The textures are determined at runtime so trying to do a wrapped texture is not an option.

I have all the code working to be able to calculate the UV’s for any given vertex on the face; the piece I can’t seem to figure out is how to set up the vertex elements with your (somewhat confusing / inscrutable) MappingMode and ReferenceMode paradigms.

Is there any chance you have any, or could write, some example code showing how to build a simple cube, and apply 2 different materials / textures to 2 different faces on the cube? It would be INCREDIBLY helpful. All my outputs are in GLB, if that makes a difference.

@OBCad

Thanks for contacting support.

We are looking into your inquiry and checking related information at our side. We will get back to you shortly with our feedback.

@OBCad

Please find attached sample code for building a simple cube with different materials on different faces and save to .gltf.SampleCode.zip (1.6 KB)

Hi asad.ali, I’m interested in this sample code but I cannot download the attachment because it’s restricted to the topic owner. Could you share it with me please? Thank you!

@rcamachophysna

Below is the code snippet content from above file:

using Aspose.ThreeD;
using Aspose.ThreeD.Entities;
using Aspose.ThreeD.Formats;
using Aspose.ThreeD.Shading;
using Aspose.ThreeD.Utilities;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace Test
{
    class SampleCode
    {

        public static void CreateBoxWithDifferentMaterials()
        {
            var box = new Mesh();
            var controlPoints = box.ControlPoints;
            controlPoints.Add(new Vector4(-5.0, 0.0, 5.0, 1.0));
            controlPoints.Add(new Vector4(5.0, 0.0, 5.0, 1.0));
            controlPoints.Add(new Vector4(5.0, 10.0, 5.0, 1.0));
            controlPoints.Add(new Vector4(-5.0, 10.0, 5.0, 1.0));
            controlPoints.Add(new Vector4(-5.0, 0.0, -5.0, 1.0));
            controlPoints.Add(new Vector4(5.0, 0.0, -5.0, 1.0));
            controlPoints.Add(new Vector4(5.0, 10.0, -5.0, 1.0));
            controlPoints.Add(new Vector4(-5.0, 10.0, -5.0, 1.0));

            // Create polygons to mesh
            // Front face (Z+)
            box.CreatePolygon(0, 1, 2, 3);
            // Right side (X+)
            box.CreatePolygon(1, 5, 6, 2);
            // Back face (Z-)
            box.CreatePolygon(5, 4, 7, 6);
            // Left side (X-)
            box.CreatePolygon(4, 0, 3, 7);
            // Bottom face (Y-)
            box.CreatePolygon(0, 4, 5, 1);
            // Top face (Y+)
            box.CreatePolygon(3, 2, 6, 7);

            //To simplify the demo we generate the normal and uv automatically instead of 
            //writing a lot of code here, it's not perfect but enough for demostration.

            //in order to generate UV automatically, normal data are required.
            var normals = PolygonModifier.GenerateNormal(box);
            box.VertexElements.Add(normals);

            //generate UV
            var uv = PolygonModifier.GenerateUV(box);
            box.VertexElements.Add(uv);

            //create node and scene that owns this box
            var scene = new Scene();
            var node = scene.RootNode.CreateChildNode(box);
            //prepare materials to the node
            node.Materials.Add(CreateMaterial(Color.CadetBlue, "Mat-1"));
            node.Materials.Add(CreateMaterial(Color.Goldenrod, "Mat-2"));
            node.Materials.Add(CreateMaterial(Color.FloralWhite, "Mat-3"));
            //assign materials to different polygon by using VertexElementMaterial

            var mats = (VertexElementMaterial)box.CreateElement(VertexElementType.Material);
            //Default mapping mode for material is AllSame
            //we need per polygon material
            mats.MappingMode = MappingMode.Polygon;
            //assign material indices to the polygons so that
            // Polygon 0 - 2(Mat-3)
            // Polygon 1 - 1(Mat-2)
            // Polygon 2 - 0(Mat-1)
            // Polygon 3 - 0(Mat-1)
            // Polygon 4 - 1(Mat-2)
            // Polygon 5 - 2(Mat-3)
            mats.SetIndices(new int[] { 2, 1, 0, 0, 1, 2 });
            //save to glb
            var opt = new GLTFSaveOptions(FileFormat.GLTF2_Binary);
            opt.EmbedAssets = true;//the output will embed the textures
            //The GLTF's structure of this box contains 3 primitives which uses different materials
            scene.Save("cube.glb", opt);
        }


        private static Material CreateMaterial(Color color, string text)
        {
            //create a texture using System.Drawing
            //just a plain color background with a text on it
            var tex = new Texture();
            tex.FileName = text + ".png";
            using(var img = new Bitmap(128, 128, PixelFormat.Format24bppRgb))
            {
                using (var g = Graphics.FromImage(img))
                {
                    using (var font = new Font(FontFamily.GenericSansSerif, 20))
                    {
                        g.Clear(color);
                        g.DrawString(text, font, Brushes.Black, new Point(0, 0));
                    }

                }
                //embed the image as png format to the texture
                using (var ms = new MemoryStream())
                {
                    img.Save(ms, ImageFormat.Png);
                    tex.Content = ms.ToArray();
                }
            }
            //create an empty material to use this texture
            //when the scene get exported to gltf/glb 2.0, Aspose.3D will convert non-pbr materials to pbr materials
            var mat = new LambertMaterial();
            mat.SetTexture(Material.MapDiffuse, tex);
            return mat;
        }

    }
}

Thank you very much