javascript - 多个对象 Glsl

标签 javascript glsl webgl

当我寻找独立绘制两个对象时,我在使用 Glsl 时遇到了一些问题。当我搜索查看代码结果时,编译器考虑的对象是第一个纹理,而纹理是第二个。此外,我不明白如何使用独立的方式设置对象的初始位置相同的着色器。 这是我的代码:

var program;
var gl;
var shaderDir; 
var baseDir;
var missileModel;
var pigModel;
var missileStr = 'model/R73-Ready.obj';
var missileTexture = 'model/R73 Texture.png';
var modelStr = 'model/mount.obj';
var modelTexture = 'model/ground_grass_3264_4062_Small.jpg';


function main() {
    
    var lastUpdateTime = (new Date).getTime();
    
    var Rx = 0.0;
    var Ry = 0.0;
    var Rz = 0.0;
    var S  = 0.5;

    utils.resizeCanvasToDisplaySize(gl.canvas);
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
    gl.clearColor(0.85, 1.0, 0.85, 1.0); 
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.enable(gl.DEPTH_TEST);

    
    //Here we extract the position of the vertices, the normals, the indices, and the uv coordinates
    var missileVertices = missileModel.vertices;
    var missileNormals = missileModel.vertexNormals;
    var missileIndices = missileModel.indices;
    var missileTexCoords = missileModel.textures;
    
    var pigVertices = pigModel.vertices;
    var pigNormals = pigModel.vertexNormals;
    var pigIndices = pigModel.indices;
    var pigTexCoords = pigModel.textures;
    //###################################################################################
   
    var  positionAttributeLocation = gl.getAttribLocation(program, "a_position");  
    var uvAttributeLocation = gl.getAttribLocation(program, "a_uv");  
    var matrixLocation = gl.getUniformLocation(program, "matrix");  
    var textLocation = gl.getUniformLocation(program, "u_texture");

    var perspectiveMatrix = utils.MakePerspective(120, gl.canvas.width/gl.canvas.height, 0.1, 100.0);
    var viewMatrix = utils.MakeView(0, 0.0, 3.0, 0.0, 0.0);
    
    //drawing land
    var vao = gl.createVertexArray();
    gl.bindVertexArray(vao);

    var positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pigVertices), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(positionAttributeLocation);
    gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

    var uvBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pigTexCoords), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(uvAttributeLocation);
    gl.vertexAttribPointer(uvAttributeLocation, 2, gl.FLOAT, false, 0, 0);

    var indexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(pigIndices), gl.STATIC_DRAW); 

    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);

    var image = new Image();
    image.src = baseDir+modelTexture;
    image.onload= function() {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.generateMipmap(gl.TEXTURE_2D);
    };
    
    
   //drawing the missile
    
    var missile = gl.createVertexArray();
    gl.bindVertexArray(missile);

    var misspositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, misspositionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(missileVertices), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(positionAttributeLocation);
    gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

    var missileuvBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, missileuvBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(missileTexCoords), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(uvAttributeLocation);
    gl.vertexAttribPointer(uvAttributeLocation, 2, gl.FLOAT, false, 0, 0);

    var missindexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, missindexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(missileIndices), gl.STATIC_DRAW); 

    var misstexture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, misstexture);

    var missimage = new Image();
    missimage.src = baseDir+missileTexture;
    missimage.onload= function() {
    gl.bindTexture(gl.TEXTURE_2D, misstexture);
              gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, missimage);
              gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
              gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.generateMipmap(gl.TEXTURE_2D);
    };
    
    
    drawScene();
    
    function animate(){
    var currentTime = (new Date).getTime();
   if(lastUpdateTime != null){
      //var deltaC = 0; //(30 * (currentTime - lastUpdateTime)) / 1000.0;
      Rx = 90;
      Ry = 90;
      Rz = 90;    
    }
    worldMatrix = utils.MakeWorld(0.0, 0.0, 0.0, Rx, Ry, Rz, S);
    lastUpdateTime = currentTime;               
  }
    
    function drawScene() {
    animate();

    utils.resizeCanvasToDisplaySize(gl.canvas);
    gl.clearColor(0.85, 0.85, 0.85, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    var viewWorldMatrix = utils.multiplyMatrices(viewMatrix, worldMatrix);
    var projectionMatrix = utils.multiplyMatrices(perspectiveMatrix, viewWorldMatrix);

    gl.uniformMatrix4fv(matrixLocation, gl.FALSE, utils.transposeMatrix(projectionMatrix));

    gl.activeTexture(gl.TEXTURE0);
    gl.uniform1i(textLocation, misstexture);

    gl.bindVertexArray(missile);
    gl.drawElements(gl.TRIANGLES, missileIndices.length, gl.UNSIGNED_SHORT, 0 );
        
    gl.activeTexture(gl.TEXTURE0);
    gl.uniform1i(textLocation, texture);

    gl.bindVertexArray(vao);
    gl.drawElements(gl.TRIANGLES, pigIndices.length, gl.UNSIGNED_SHORT, 0 );


    window.requestAnimationFrame(drawScene);
  }
}

async function init(){
  
    var path = window.location.pathname;
    var page = path.split("/").pop();
    baseDir = window.location.href.replace(page, '');
    shaderDir = baseDir+"shaders/";

    var canvas = document.getElementById("c");
    gl = canvas.getContext("webgl2");
    if (!gl) {
        document.write("GL context not opened");
        return;
    }

    await utils.loadFiles([shaderDir + 'vs.glsl', shaderDir + 'fs.glsl'], function (shaderText) {
      var vertexShader = utils.createShader(gl, gl.VERTEX_SHADER, shaderText[0]);
      var fragmentShader = utils.createShader(gl, gl.FRAGMENT_SHADER, shaderText[1]);
      program = utils.createProgram(gl, vertexShader, fragmentShader); 

    });
    gl.useProgram(program);
    
    //###################################################################################
    //This loads the obj model in the pigModel variable
    var pigObjStr = await utils.get_objstr(baseDir+ missileStr);
    missileModel = new OBJ.Mesh(pigObjStr);
   
    var pigObjStr1 = await utils.get_objstr(baseDir+ modelStr);
    pigModel = new OBJ.Mesh(pigObjStr1);

    main();
}

window.onload = init;

最佳答案

bindTexture将命名纹理绑定(bind)到纹理目标和当前纹理单元。当前纹理单元由activeTexture设置。
纹理单元是命名纹理对象和纹理采样器制服之间的绑定(bind)点。采样器制服必须由纹理单元设置,而不是纹理对象名称。


您必须将纹理单元(索引)分配给纹理采样器制服,并且在绘制对象之前必须将纹理绑定(bind)到纹理单元:

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, misstexture);
gl.uniform1i(textLocation, 0); // 0 because 'misstexture' is bound to texture unit 0  

gl.bindVertexArray(missile);
gl.drawElements(gl.TRIANGLES, missileIndices.length, gl.UNSIGNED_SHORT, 0);
        
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(textLocation, 0);  // 0 because 'texture' is bound to texture unit 0

gl.bindVertexArray(vao);
gl.drawElements(gl.TRIANGLES, pigIndices.length, gl.UNSIGNED_SHORT, 0);

当然可以将纹理绑定(bind)到不同的纹理单元:

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, misstexture);

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture);

并在绘制对象之前设置纹理采样器统一

gl.uniform1i(textLocation, 0); // 0 because 'misstexture' is bound to texture unit 0 
gl.bindVertexArray(missile);
gl.drawElements(gl.TRIANGLES, missileIndices.length, gl.UNSIGNED_SHORT, 0);

gl.uniform1i(textLocation, 1);  // 1 because 'texture' is bound to texture unit 1
gl.bindVertexArray(vao);
gl.drawElements(gl.TRIANGLES, pigIndices.length, gl.UNSIGNED_SHORT, 0);

关于javascript - 多个对象 Glsl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63550572/

相关文章:

opengl - 标准化值意味着什么?

javascript - Three.js 三 Angular 形未绘制

text - WebGL:文本渲染和混合问题

html - 使用预乘 alpha 时,WebGL 中的 Alpha 渐变不平滑

javascript - MongoDB 聚合总是返回 0 值

javascript - 禁用 next.js 服务器端渲染以防止窗口未定义错误

javascript - 如何获取元素的高度,然后通过 css 应用该值

qt - 奇怪的 alpha 混合结果与 ShaderEffectItem

javascript - 检测 Google 折线图的缩放事件?

c - 我们如何从 GLSL 中获取变量值?