I’m trying to use the same simple custom shader on two different entities but with different UV values.
varying vec2 vUv1;
uniform sampler2D uDiffuseMap;
void main(void)
{
vec4 color = texture2D(uDiffuseMap, vUv1);
gl_FragColor = color;
}
- but it seems that the same set of UVs (
aUv1: pc.SEMANTIC_TEXCOORD1
) is shared between the shaders, using the same value
- I’ve tried creating a second identical shader that uses
aUv2: pc.SEMANTIC_TEXCOORD2
and tried using mesh.setUvs(2, textureCoords);
to set it. But when I check the vertex buffer, it seems that the new attribute isn’t being added.
A minimal test is here https://playcanvas.com/editor/scene/1757000.
- Is it possible to re-use the same shader but with different attribute values?
- How can I add and use new attributes?
are you calling mesh.update() after mesh.setUvs? Check its parameters too.
Like this?
mesh.setUvs(2, textureCoords);
mesh.update();
Also,
let shaderDefinition = {
attributes: {
aPosition: pc.SEMANTIC_POSITION,
aUv2: pc.SEMANTIC_TEXCOORD2
},
vshader: vertexShader,
fshader: fragmentShader
};
bump
I’ve just revisited this topic and was considering raising this as a bug unless someone can confirm that this is expected behaviour.
To reiterate:
Given two entities both using the same shader and the following code with this.offset
set to different values
let meshInstance = this.entity.render.meshInstances[0];
let mesh = meshInstance.mesh;
let textureCoords = [];
if(this.offset == 0)
textureCoords = [0, 1, 0, 0, 0.5, 1, 0.5, 0,];
else
textureCoords = [0.5, 1, 0.5, 0, 1, 1, 1, 0,];
mesh.setUvs(1, textureCoords);
mesh.update();
I would like to see the following result:

However, I get:

This would make sense if both entities share the same shader rather than having their own instance.
An explanation would be appreciated. 
do you have one mesh or two meshes?
It should work for two meshes, each mesh would have different UVs and use different part of the texture.
But if this is just a single mesh, you only update it twice and the second update wins, overwriting the first one.
Two separate meshes.
Project here: PlayCanvas | HTML5 Game Engine
under the hood, there is just a single mesh that is rendered twice, as both of those use ‘plane’ render type.
OK. Makes sense.
Is there a way of forcing two separate meshes?
you’d need to create a mesh, create a mesh instance and assign them to the render component from script. Editor caches all meshes under the hood for performance reason, so there is only one per type.
You could also modify your code. Get mesh from mesh instance, but do not modify it, but create a copy based on it, create new mesh instance as well and assign it all back to your component
1 Like
This example does something similar in a way:
https://playcanvas.vercel.app/#/graphics/ground-fog
const mesh = pc.Mesh.fromGeometry(
app.graphicsDevice,
new pc.PlaneGeometry({ widthSegments: 20, lengthSegments: 20 })
);
const meshInstance = new pc.MeshInstance(mesh, material);
const ground = new pc.Entity();
ground.addComponent('render', {
meshInstances: [meshInstance],
material: material,
castShadows: false,
receiveShadows: false
});
And now I just hope this is not engine 2 only API 