Material not showing on simple plane mesh

I have the following script which draws a simple plane. However, the material I set in the editor for the material attribute isn’t working. The plane is always black. What am I missing?

var Plane = pc.createScript('plane');

Plane.attributes.add('material', {
    type: 'asset',
    assetType: 'material',
    title: 'Material',
    description: 'The material to apply to the 3D text mesh'
});

// initialize code called once per entity
Plane.prototype.initialize = function () {
    const vertices = new Float32Array([
        -0.5, 0.5, 0, // top, left
        -0.5, -0.5, 0, // bottom, left
        0.5, 0.5, 0, // top, right
        0.5, -0.5, 0, // bottom, right
    ]);


    // Prepare the mesh to be created into a mesh instance
    this.mesh = new pc.Mesh(this.app.graphicsDevice);
    this.mesh.setPositions(vertices);
    this.mesh.update(pc.PRIMITIVE_TRISTRIP);

    var material = this.material ? this.material.resource : new pc.StandardMaterial()

    // Create the mesh instance
    var meshInstance = new pc.MeshInstance(this.mesh, material);

    this.entity.addComponent('render', {
        meshInstances: [meshInstance],
    });

};

image

If you define the positions of vertices, you also need to provide the normals, otherwise the engine doesn’t know how to paint it. Check the mesh generation example to see how to set up normals:

mesh.setNormals(pc.calculateNormals(positions, indexArray));

https://playcanvas.github.io/#/graphics/mesh-generation

Since I’m using TRISTRIP I don’t think I would need indices.

Maybe TRIPSTRIP isn’t correctly supported for Mesh

I’ll switching to using TRIANGLES and define indices and calculate normals

Yes, that did the trick.

The example code in mesh.js is incorrect and needs updating to the following code to produce correct results

    const mesh = new pc.Mesh(this.app.graphicsDevice);
    const positions = new Float32Array([
        0, 0, 0, // pos 0
        1, 0, 0, // pos 1
        1, 1, 0, // pos 2
        0, 1, 0  // pos 3
    ]);
    
    const uvs = new Float32Array([
        0, 1, // uv 3
        1, 1, // uv 2
        1, 0, // uv 1
        0, 0, // uv 0
    ]);
    const indices = [
        0, 1, 2, // triangle 0
        0, 2, 3  // triangle 1
    ];
    mesh.setPositions(positions);
    mesh.setNormals(pc.calculateNormals(positions, indices));
    mesh.setUvs(0, uvs);
    mesh.setIndices(indices);
    mesh.update();

image

Technically, normals are not always needed, for example, when you generate a collision mesh. However, I do agree that the example needs an update. I’ve created an ticket. Would you like to submit a PR?

Submitted. Thanks for your help

1 Like