2014-10-16 2 views
0

немного утерян здесь. пытаясь установить разные текстуры на разные вершины. WebGL делает это чрезвычайно излишне сложным. В основном у меня есть текстовый файл с матрицами вершин, которые я хочу, который работает. (пример здесь: http://jdmdev.net/Foundation/index.html)Несколько шейдерных программ для получения различных текстур

Но теперь, чтобы установить разные текстуры, мне нужно будет сделать что-то, называемое «текстурирование atlassing», которое абсолютно нулевая документация о том, как реализовать это онлайн ... в любом месте.

Я очень новичок в WebGL, но имею обширный опыт программирования, поэтому я могу понять любые концепции, предоставленные мне .. если я могу просто увидеть что-то работающее или, по крайней мере, документацию на нем.

Так что я думаю, что текстурирование текстуры не соответствует действительности. Однако, если я не согласен с конвейером WebGL, как и считаю. Не могу ли я создать несколько программ шейдеров/вершин? Если да, то как я могу это сделать? Мне не нужен прямой пример, но только какой-то код будет творить чудеса. Мне просто нужно увидеть это один раз, и я это получу, но невозможно найти какой-либо полезный материал в Интернете, потому что это так ново. Я ценю любую помощь.

Не уверен, как любой код будет помочь с ответом на этот вопрос, но вот мой код, который я использовал в основном из learningwebgltutorials.com

<script id="shader-fs" type="x-shader/x-fragment"> 
    precision mediump float; 

    varying vec2 vTextureCoord; 

    uniform sampler2D uSampler; 
    uniform sampler2D uSampler2; 

    void main(void) { 
     gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 
    } 
</script> 

<script id="shader-vs" type="x-shader/x-vertex"> 
    attribute vec3 aVertexPosition; 
    attribute vec2 aTextureCoord; 

    uniform mat4 uMVMatrix; 
    uniform mat4 uPMatrix; 

    varying vec2 vTextureCoord; 

    void main(void) { 
     gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 
     vTextureCoord = aTextureCoord; 
    } 
</script> 

<script id="shader2-fs" type="x-shader/x-fragment"> 
    precision mediump float; 

    varying vec2 vTextureCoord; 

    uniform sampler2D uSampler; 
    uniform sampler2D uSampler2; 

    void main(void) { 
     gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 
    } 
</script> 

<script id="shader2-vs" type="x-shader/x-vertex"> 
    attribute vec3 aVertexPosition; 
    attribute vec2 aTextureCoord; 

    uniform mat4 uMVMatrix; 
    uniform mat4 uPMatrix; 

    varying vec2 vTextureCoord; 

    void main(void) { 
     gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 
     vTextureCoord = aTextureCoord; 
    } 
</script> 

<script type="text/javascript"> 

    var gl; 

    function initGL(canvas) { 
     try { 
      gl = canvas.getContext("experimental-webgl"); 
      gl.viewportWidth = canvas.width; 
      gl.viewportHeight = canvas.height; 
     } catch (e) { 
     } 
     if (!gl) { 
      alert("Could not initialise WebGL, sorry :-("); 
     } 
    } 


    function getShader(gl, id) { 
     var shaderScript = document.getElementById(id); 
     if (!shaderScript) { 
      return null; 
     } 

     var str = ""; 
     var k = shaderScript.firstChild; 
     while (k) { 
      if (k.nodeType == 3) { 
       str += k.textContent; 
      } 
      k = k.nextSibling; 
     } 

     var shader; 
     if (shaderScript.type == "x-shader/x-fragment") { 
      shader = gl.createShader(gl.FRAGMENT_SHADER); 
     } else if (shaderScript.type == "x-shader/x-vertex") { 
      shader = gl.createShader(gl.VERTEX_SHADER); 
     } else { 
      return null; 
     } 

     gl.shaderSource(shader, str); 
     gl.compileShader(shader); 

     if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 
      alert(gl.getShaderInfoLog(shader)); 
      return null; 
     } 

     return shader; 
    } 


    var shaderProgram; 

    function initShaders() { 
     var fragmentShader = getShader(gl, "shader-fs"); 
     var vertexShader = getShader(gl, "shader-vs"); 

     shaderProgram = gl.createProgram(); 
     gl.attachShader(shaderProgram, vertexShader); 
     gl.attachShader(shaderProgram, fragmentShader); 
     gl.linkProgram(shaderProgram); 

     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { 
      alert("Could not initialise shaders"); 
     } 

     gl.useProgram(shaderProgram); 

     shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); 
     gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); 

     shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); 
     gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); 

     shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); 
     shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); 
     shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); 
    } 


    function handleLoadedTexture(texture) { 
     gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 
     gl.bindTexture(gl.TEXTURE_2D, texture); 
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 

     gl.bindTexture(gl.TEXTURE_2D, null); 
    } 


    var mudTexture; 
    var rockTexture; 

    function initTexture() { 
     mudTexture = gl.createTexture(); 
     mudTexture.image = new Image(); 
     mudTexture.image.onload = function() { 
      handleLoadedTexture(mudTexture) 
     } 

     mudTexture.image.src = "mud.gif"; 

     rockTexture = gl.createTexture(); 
     rockTexture.image = new Image(); 
     rockTexture.image.onload = function() { 
      handleLoadedTexture(rockTexture) 
     } 

     rockTexture.image.src = "rockstar.gif"; 
    } 


    var mvMatrix = mat4.create(); 
    var mvMatrixStack = []; 
    var pMatrix = mat4.create(); 

    function mvPushMatrix() { 
     var copy = mat4.create(); 
     mat4.set(mvMatrix, copy); 
     mvMatrixStack.push(copy); 
    } 

    function mvPopMatrix() { 
     if (mvMatrixStack.length == 0) { 
      throw "Invalid popMatrix!"; 
     } 
     mvMatrix = mvMatrixStack.pop(); 
    } 


    function setMatrixUniforms() { 
     gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); 
     gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); 
    } 


    function degToRad(degrees) { 
     return degrees * Math.PI/180; 
    } 



    var currentlyPressedKeys = {}; 

    function handleKeyDown(event) { 
     currentlyPressedKeys[event.keyCode] = true; 
    } 


    function handleKeyUp(event) { 
     currentlyPressedKeys[event.keyCode] = false; 
    } 


    var pitch = 0; 
    var pitchRate = 0; 

    var yaw = 0; 
    var yawRate = 0; 

    var xPos = 10; 
    var yPos = 0.4; 
    var zPos = 10; 

    var speed = 0; 

    function handleKeys() { 
     if (currentlyPressedKeys[33]) { 
      // Page Up 
      pitchRate = 0.1; 
     } else if (currentlyPressedKeys[34]) { 
      // Page Down 
      pitchRate = -0.1; 
     } else { 
      pitchRate = 0; 
     } 

     if (currentlyPressedKeys[37] || currentlyPressedKeys[65]) { 
      // Left cursor key or A 
      yawRate = 0.1; 
     } else if (currentlyPressedKeys[39] || currentlyPressedKeys[68]) { 
      // Right cursor key or D 
      yawRate = -0.1; 
     } else { 
      yawRate = 0; 
     } 

     if (currentlyPressedKeys[38] || currentlyPressedKeys[87]) { 
      // Up cursor key or W 
      speed = 0.01; 
     } else if (currentlyPressedKeys[40] || currentlyPressedKeys[83]) { 
      // Down cursor key 
      speed = -0.01; 
     } else { 
      speed = 0; 
     } 

    } 


    var worldVertexPositionBuffer = null; 
    var worldVertexTextureCoordBuffer = null; 

    function handleLoadedWorld(data) { 
     var lines = data.split("\n"); 
     var vertexCount = 0; 
     var vertexPositions = []; 
     var vertexTextureCoords = []; 
     for (var i in lines) { 
      var vals = lines[i].replace(/^\s+/, "").split(/\s+/); 
      if (vals.length == 6 && vals[0] != "//") { 
       // It is a line describing a vertex; get X, Y and Z first 
       vertexPositions.push(parseFloat(vals[0])); 
       vertexPositions.push(parseFloat(vals[1])); 
       vertexPositions.push(parseFloat(vals[2])); 
       //document.write(vertexPositions[0]); 
       // And then the texture coords 
       vertexTextureCoords.push(parseFloat(vals[3])); 
       vertexTextureCoords.push(parseFloat(vals[4])); 
       //document.write(vals[4]) + "<br/>"); 
       vertexCount += 1; 
      } 
     } 

     worldVertexPositionBuffer = gl.createBuffer(); 
     gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer); 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW); 
     worldVertexPositionBuffer.itemSize = 3; 
     worldVertexPositionBuffer.numItems = vertexCount; 

     worldVertexTextureCoordBuffer = gl.createBuffer(); 
     gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer); 
     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexTextureCoords), gl.STATIC_DRAW); 
     worldVertexTextureCoordBuffer.itemSize = 2; 
     worldVertexTextureCoordBuffer.numItems = vertexCount; 

     document.getElementById("loadingtext").textContent = ""; 
    } 


    function loadWorld() { 
     var request = new XMLHttpRequest(); 
     request.open("GET", "world.txt"); 
     request.onreadystatechange = function() { 
      if (request.readyState == 4) { 
       handleLoadedWorld(request.responseText); 
      } 
     } 
     request.send(); 
    } 

    function loadTextureValues() { 
     var request = new XMLHttpRequest(); 
     request.open("GET", "world.txt"); 
     request.onreadystatechange = function() { 
      if (request.readyState == 4) { 
       getCorrectTexture(request.responseText); 
      } 
     } 
     request.send(); 
    } 

    var matchWithTexture = {}; 

    function getCorrectTexture(data) 
    { 
     var lines = data.split("\n"); 
     var vertexCount = 0; 
     var vertexTextureValueCoords = []; 

     for (var i in lines) { 
      var vals = lines[i].replace(/^\s+/, "").split(/\s+/); 
      if (vals.length == 6 && vals[0] != "//") 
      { 
       //document.write(vertexTextureValueCoords.push(parseFloat(vals[1])) + "</br>"); 
       vertexTextureValueCoords.push(parseFloat(vals[5])); 
       matchWithTexture[vertexCount] = vertexTextureValueCoords[vertexCount]; 
       vertexCount++; 
      } 
     } 
    } 



    function drawScene() { 
     gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 

     if (worldVertexTextureCoordBuffer == null || worldVertexPositionBuffer == null) { 
      return; 
     } 

     mat4.perspective(45, gl.viewportWidth/gl.viewportHeight, 0.1, 100.0, pMatrix); 

     mat4.identity(mvMatrix); 

     mat4.rotate(mvMatrix, degToRad(-pitch), [1, 0, 0]); 
     mat4.rotate(mvMatrix, degToRad(-yaw), [0, 1, 0]); 
     mat4.translate(mvMatrix, [-xPos, -yPos, -zPos]); 

     gl.activeTexture(gl.TEXTURE0); 
     gl.bindTexture(gl.TEXTURE_2D, mudTexture); 
     gl.activeTexture(gl.TEXTURE1); 
     gl.bindTexture(gl.TEXTURE_2D, rockTexture); 

     loadTextureValues(); 
     for(var key in matchWithTexture) 
     { 
      //document.write(matchWithTexture[key] + "<br/>"); 
      if(matchWithTexture[key] == 1) 
      { 
       gl.uniform1i(shaderProgram.samplerUniform, 0); 
      } 
      else { 
       gl.uniform1i(shaderProgram.samplerUniform, 1); 
      } 
     } 



     gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer); 
     gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, worldVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); 

     gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer); 
     gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, worldVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); 

     setMatrixUniforms(); 
     gl.drawArrays(gl.TRIANGLES, 0, worldVertexPositionBuffer.numItems); 
    } 


    var lastTime = 0; 
    // Used to make us "jog" up and down as we move forward. 
    var joggingAngle = 0; 

    function animate() { 
     var timeNow = new Date().getTime(); 
     if (lastTime != 0) { 
      var elapsed = timeNow - lastTime; 

      if (speed != 0) { 
       xPos -= Math.sin(degToRad(yaw)) * speed * elapsed; 
       zPos -= Math.cos(degToRad(yaw)) * speed * elapsed; 

       joggingAngle += elapsed * 0.6; // 0.6 "fiddle factor" - makes it feel more realistic :-) 
       yPos = Math.sin(degToRad(joggingAngle))/20 + 0.4 
      } 

      yaw += yawRate * elapsed; 
      pitch += pitchRate * elapsed; 

     } 
     lastTime = timeNow; 
    } 


    function tick() { 
     requestAnimFrame(tick); 
     handleKeys(); 
     drawScene(); 
     animate(); 
    } 



    function webGLStart() { 
     var canvas = document.getElementById("lesson10-canvas"); 
     initGL(canvas); 
     initShaders(); 
     initTexture(); 
     loadWorld(); 

     gl.clearColor(0.0, 0.0, 0.0, 1.0); 
     gl.enable(gl.DEPTH_TEST); 

     document.onkeydown = handleKeyDown; 
     document.onkeyup = handleKeyUp; 

     tick(); 
    } 

</script> 

Так все, что я сделал, было создать 2-ую программу шейдера/вершина, и ее до сих пор работает. Итак, как я могу реализовать их с другой информацией из первых шейдерных/вершинных программ?

И последний вопрос: было бы просто стоить больше использовать библиотеку вместо того, чтобы пытаться делать все в webgl? Я имею в виду, что со всеми поисковыми запросами Google, которые я выполнил в webgl, больше всего все примеры/учебники выполняются с использованием тр.js или babylon.js..etc. Мне просто интересно, стоит ли даже пытаться делать то, что я делаю. Я предполагаю, что вопрос будет, профессиональные настройки хотят, чтобы я сделал прямо в webgl, или я (скорее всего) буду использовать библиотеку? Я даже не планирую программировать webgl, а просто знаю, если он когда-нибудь появится в интервью.

РЕШЕНИЕ VIA NO-ТЕКСТУРЫ Aliasing

https://github.com/jordmax12/WebGL/blob/master/Foundation%205/foundation_2.js

Поскольку я уже синтаксический анализ информации из текстового файла для вершин и текстурных координат, то должен быть способ сделать это для самой текстуры (без наложения текстур).

+0

Существует [простой пример текстурирования в нижней части этой страницы, описывающий, как текстурировать куб с 6 лицами] (http://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html). Вы используете текстурные координаты, чтобы выбрать, какая часть текстур сопоставляет вершинам. Таким образом, любой треугольник может выбрать другую часть текстуры. Обратите внимание, что если два смежных треугольника используют разную текстуру, эти треугольники НЕ разделяют вершины. Это связано с тем, что вершина состоит из как положения, так и текстурных коордов, и поскольку tex-координаты должны быть разными, вершины не могут быть разделены. – gman

+0

@gman Прохладный! Фактически я выяснил способ разобрать простой текстовый файл и связать текстуру с этим без наложения вообще. Я отправлю ссылку в своем вопросе, если кто-то захочет это сделать. Я чувствую, что это намного проще и более «программировать». –

ответ

0

Вы можете использовать разные текстуры и шейдеры на разных вершинах, если вы рисуете их по одному. Проблема в том, что это довольно неэффективно. Поэтому для хорошей производительности я не думаю, что есть способ обойти atlasing - вот почему все это делают.

Мне не известно о любом использовании трио.js для упрощения атласа (но я не очень хорошо знаком с трио.js).

Он должен быть прямым для реализации утилиты, которая рисует текстуры на большом холсте, создавая атлас «на лету» во время выполнения и отслеживая координаты. После установки инструмент будет в основном преобразовывать координаты и имена текстур или идентификаторы в чистый координатный массив (включая координаты текстуры).

Следует ли использовать библиотеку, действительно зависит от того, что вы планируете делать. Если API-интерфейс с сохраненным режимом работает для вашего случая использования, это, вероятно, хорошая идея и более удобно использовать three.js.

+0

у вас возникнет пример вашего собственного или, возможно, ресурса, который вы использовали для его создания? Я могу окутать голову в алгоритмы отслеживания атак и cpu poker betting, но нет ничего, что я нашел, чтобы показать, как делать то, что вы описываете, но то, что вы описываете, именно то, что я пытаюсь сделать. –

Смежные вопросы