登峰造极境

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Programming
  3. babylon.js
  4. 正文

babylonjs-Shader的gl_VertexID测试验证

2025-04-21

一、场景

想通过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;
};
标签: 暂无
最后更新:2025-04-21

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号