一、场景
想通过gl_VertexID,来实现一个立方体Mesh,给不同面贴不同的材质,且方向放正。所以做了验证。
代码:https://playground.babylonjs.com/#XP2WCV#19
二、验证结果
验证不同gl_VertexID的区域
gl_VertexID=1或2或3时,显示的区域如下图。和预期的完全不一致,经过调研可知不同的人画的Box的gl_VertexID顺序完全不一致,所以不建议用gl_VertexID来区别面。

验证Box的各个面的gl_VertexID范围
经过验证,不同面的gl_VertexID范围:
void main(void) {
int vId = int(vGl_VertexID)+1;
vec3 vNormal = worldNormal;//normalize(worldNormal);
vec4 defaultColor = vec4(0.1, 0.7, 0.1, 1.0);
if (vId>=0 && vId<=3){
gl_FragColor = texture2D(textureSampler1, vUv1);
}else if(vId>=4&&vId<=7){
gl_FragColor = texture2D(textureSampler2, vUv1);
}else if(vId>=8&&vId<=11){
gl_FragColor = texture2D(textureSampler3, vUv1);
}else if(vId>=12&&vId<=15){
gl_FragColor = texture2D(textureSampler4, vUv1);
}else if(vId>=16&&vId<=19){
gl_FragColor = texture2D(textureSampler5, vUv1);
}else if(vId>=20&&vId<=23){
gl_FragColor = texture2D(textureSampler6, vUv1);
}else{
gl_FragColor = defaultColor;
}
}

完整代码:
var createScene = function () {
// This creates a basic Babylon Scene object (non-mesh)
var scene = new BABYLON.Scene(engine);
// This creates and positions a free camera (non-mesh)
const camera = new BABYLON.ArcRotateCamera("camera", Math.PI / 2, Math.PI / 4, 200, BABYLON.Vector3.Zero(), scene);
// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
var skybox = BABYLON.Mesh.CreateBox("BackgroundSkybox", 5000, scene, undefined, BABYLON.Mesh.BACKSIDE);
var backgroundMaterial = new BABYLON.BackgroundMaterial("backgroundMaterial", scene);
backgroundMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/TropicalSunnyDay", scene);
backgroundMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
skybox.material = backgroundMaterial;
const texture1 = new BABYLON.Texture("https://i.endpot.com/image/B3SD3/纹理1.png", scene);
const texture2 = new BABYLON.Texture("https://i.endpot.com/image/P0K5X/纹理2.png", scene);
const texture3 = new BABYLON.Texture("https://i.endpot.com/image/O6ZY5/纹理3.png", scene);
const texture4 = new BABYLON.Texture("https://i.endpot.com/image/UMKPO/纹理4.png", scene);
const texture5 = new BABYLON.Texture("https://i.endpot.com/image/D32P3/纹理5.png", scene);
const texture6 = new BABYLON.Texture("https://i.endpot.com/image/LS1RP/纹理6.png", scene);
const shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
vertexSource: `
precision highp float;
// Attributes
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 vUv;
varying vec2 vUv1;
varying vec3 worldNormal;
varying float vGl_VertexID;
// Uniforms
uniform mat4 worldViewProjection;
// Varying
varying vec4 vPosition;
varying vec3 vNormal;
attribute vec3 aNormal; // 输入法线
//attribute int gl_VertexID; // 输入法线
uniform mat4 uModelMatrix; // 模型矩阵
void main() {
vec4 p = vec4(position, 1.0);
vPosition = p;
vNormal = normal;
gl_Position = worldViewProjection * p;
vUv1 = vec2(uv.y, uv.x); // 缩放UV坐标,使纹理重复4次
vGl_VertexID = float(gl_VertexID);
worldNormal = normalize(mat3(uModelMatrix) * aNormal);
//vgl_VertexID = gl_VertexID;
/*if (gl_VertexID < 3) { // 前、右、上表面(法线朝外)
vUv1 = uv;
} else { // 后、左、下表面(法线朝内)
vUv1 = vec2(1.0 - vUv1.x, vUv1.y); // 水平翻转UV
}*/
}
`,
fragmentSource: `
precision highp float;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec2 vUv1;
varying vec3 worldNormal;
varying float vGl_VertexID;
uniform sampler2D textureSampler1;
uniform sampler2D textureSampler2;
uniform sampler2D textureSampler3;
uniform sampler2D textureSampler4;
uniform sampler2D textureSampler5;
uniform sampler2D textureSampler6;
void main(void) {
int vId = int(vGl_VertexID)+1;
vec3 vNormal = worldNormal;//normalize(worldNormal);
vec4 defaultColor = vec4(0.1, 0.7, 0.1, 1.0);
if (vId>=0 && vId<=3){
gl_FragColor = texture2D(textureSampler1, vUv1);
}else if(vId>=4&&vId<=7){
gl_FragColor = texture2D(textureSampler2, vUv1);
}else if(vId>=8&&vId<=11){
gl_FragColor = texture2D(textureSampler3, vUv1);
}else if(vId>=12&&vId<=15){
gl_FragColor = texture2D(textureSampler4, vUv1);
}else if(vId>=16&&vId<=19){
gl_FragColor = texture2D(textureSampler5, vUv1);
}else if(vId>=20&&vId<=23){
gl_FragColor = texture2D(textureSampler6, vUv1);
}else{
gl_FragColor = defaultColor;
}
}
`,
}, {
attributes: ["position", "normal", "uv"],
uniforms: ["worldViewProjection"],
needAlphaBlending: true
});
shaderMaterial.setTexture("textureSampler1", texture1);
shaderMaterial.setTexture("textureSampler2", texture2);
shaderMaterial.setTexture("textureSampler3", texture3);
shaderMaterial.setTexture("textureSampler4", texture4);
shaderMaterial.setTexture("textureSampler5", texture5);
shaderMaterial.setTexture("textureSampler6", texture6);
const box = BABYLON.MeshBuilder.CreateBox(`b111`, { width: 40, height: 40, depth: 40 }, scene);
box.material = shaderMaterial;
box.position.y=20;
// Our built-in 'ground' shape.
var mirror = BABYLON.MeshBuilder.CreateGround("ground", { width: 1000, height: 1000 }, scene);
return scene;
};