Search code examples
javascriptglslwebglshadervertex-shader

gl_Position will not move vertex when I pass in position to shader with attribute?


Try to use createVertices() to move the coords attribute: Plunkr live code:

Question: how can I move my gl_Position with an attribute?

It works when I manually set the vec4 value:

Working

let gl;
let shaderProgram;

initGl();
createShaders();
draw();

function initGl() {
  const canvas = document.getElementById('canvas');
  gl = canvas.getContext('webgl');
  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(1, 0, 1, 1);
}

function createShaders() {
  // Think of this as a point in 3d space.
  const vs = `
    void main(void) {
      gl_Position = vec4(0.5, 0, 0, 1.0); 
      gl_PointSize = 10.0;
    }
   `; // !!!!!!!!!! this will offset the pixel by 

  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, vs);
  gl.compileShader(vertexShader);
  // Think of this as a fragment.
  const fs = `
     void main(void) {
       gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
     }
   `;
  const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, fs);
  gl.compileShader(fragmentShader);
  shaderProgram = gl.createProgram();
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);
  gl.linkProgram(shaderProgram);
  gl.useProgram(shaderProgram);
}


function draw() {
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.POINTS, 0, 1);
}

But when I add an attribute

function createVertices() {
  const coords = gl.getAttribLocation(shaderProgram, "coords");
  gl.vertexAttrib3f(coords, 0.5, 0, 0); // will not work

  const pointSize = gl.getAttribLocation(shaderProgram, "pointSize");
  gl.vertexAttrib1f(pointSize, 100); // works
}

const vs = `
    attribute vec4 coords;
    attribute float pointSize;
    void main(void) {
      gl_Position = coords;
      gl_PointSize = pointSize;
    }
  `;

Please review Plunkr live code to see complete working code.


Solution

  • You have to disableVertexAttribArray. enableVertexAttribArray enable or a generic vertex attribute array and disableVertexAttribArray disables a generic vertex attribute array.
    You have no vertex attrute array, but you have a constant attribute.

    const coords = gl.getAttribLocation(shaderProgram, "coords");
    const pointSize = gl.getAttribLocation(shaderProgram, "pointSize");
    
    gl.disableVertexAttribArray(coords); 
    gl.disableVertexAttribArray(pointSize);
    
    gl.vertexAttrib3f(coords, 0.5, 0, 0);
    gl.vertexAttrib1f(pointSize, 100);
    

    See also:


    Example:

    var gl,
    shaderProgram;
    
    initGL();
    createShaders();
    createVertices();
    draw();
    
    function initGL() {
    var canvas = document.getElementById("canvas");
    console.log(canvas);
    gl = canvas.getContext("experimental-webgl");
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(1, 1, 1, 1);
    }
    
    function createShaders() {
    var vs = "";
    vs += "attribute vec4 coords;";
    vs += "attribute float pointSize;";
    vs += "void main(void) {";
    vs += "  gl_Position = coords;";
    vs += "  gl_PointSize = pointSize;";
    vs += "}";
    
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vs);
    gl.compileShader(vertexShader);
    
    var fs = "";
    fs += "precision mediump float;";
    fs += "uniform vec4 color;";
    fs += "void main(void) {";
    fs += "  gl_FragColor = color;";
    fs += "}";
    
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fs);
    gl.compileShader(fragmentShader);
    
    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    gl.useProgram(shaderProgram);
    }
    
    function createVertices() {
    var coords = gl.getAttribLocation(shaderProgram, "coords");
    var pointSize = gl.getAttribLocation(shaderProgram, "pointSize");
    gl.disableVertexAttribArray(coords); 
    gl.disableVertexAttribArray(pointSize);
    gl.vertexAttrib3f(coords, 0.0, 0.0, 0.0);
    gl.vertexAttrib1f(pointSize, 100);
    var color = gl.getUniformLocation(shaderProgram, "color");
    gl.uniform4f(color, 1, 0, 1, 1);
    
    }
    
    function draw() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.POINTS, 0, 1);
    }
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
    </head>
    <body>
      <canvas id="canvas" width="200" height="200"></canvas>
      <script src="lib/script.js"></script>
    </body>
    </html>