javascript - 透视投影什么也没显示

标签 javascript webgl

我正在尝试关注 WebGLFundamentals.orgLearningWebGL教程,我到达了投影部分。

我创建的场景类似于 LearningWebGL Tutorial 01 (仅包含正方形):

var canvas;
var gl;

var shaderProgram;

// Vertex Shader
var positionLocation;
var uvMatrixLocation;
var pMatrixLocation;

var uvMatrix = mat4.create();
var pMatrix = mat4.create();

// Fragment Shader
var colorLocation;

var buffer = [];


function initGL() {
  canvas = document.getElementById("webgl-canvas");
  gl = WebGLUtils.setupWebGL(canvas);
  gl.viewportWidth = canvas.width;
  gl.viewportHeight = canvas.height;
}

function createShader(gl, id, type) {
  var shader;
  var shaderSrc = document.getElementById(id);

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

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

  return shader;
}

function initShaders() {

  var fragmentShader = createShader(gl, "fshader", "fragment");
  var vertexShader = createShader(gl, "vshader", "vertex");

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

  // Linka os parametros do shader
  positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
  uvMatrixLocation = gl.getUniformLocation(shaderProgram, "uvMatrix");
  pMatrixLocation = gl.getUniformLocation(shaderProgram, "pMatrix");

  gl.enableVertexAttribArray(positionLocation);

  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Não foi possível inicializar os shaders"); }
}

function initBuffers() {
  createPoly([
    1.0,  1.0,  0.0,
    -1.0,  1.0,  0.0,
    1.0, -1.0,  0.0,
    -1.0, -1.0,  0.0
  ]);
}

function draw() {
  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.useProgram(shaderProgram);

  mat4.perspective(pMatrix, Math.PI/3, 1, -10, 10);

  gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix);
  gl.uniformMatrix4fv(uvMatrixLocation, false, uvMatrix);

  buffer.forEach(function(e) {
    gl.bindBuffer(gl.ARRAY_BUFFER, e.buffer);
    gl.vertexAttribPointer(positionLocation, e.vertSize, gl.FLOAT, false, 0, 0);
    gl.drawArrays(e.primtype, 0, e.nVerts());
  });

}

window.onload = function() {
  initGL();
  initShaders();
  initBuffers();  
  draw();
}

// ---------------------------------------------------------------
// --------------------------- Utils -----------------------------
// ---------------------------------------------------------------

function createPoly(vertices) {
  var vertexBuffer;
  vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  var poly = {
    buffer:     vertexBuffer,
    vertSize:   3,
    nVerts:     function() { return vertices.length/this.vertSize; },
    primtype:   gl.TRIANGLE_STRIP
  };

  buffer.push(poly);
}
<script src="https://www.khronos.org/registry/webgl/sdk/demos/common/webgl-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>

<script id="vshader" type="x-shader/x-vertex">
attribute vec3 a_position;

uniform mat4 uvMatrix;
uniform mat4 pMatrix;

varying vec4 v_color;

void main() {
  gl_Position = pMatrix * uvMatrix * vec4(a_position, 1);
  v_color = gl_Position;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
</script>
<canvas id="webgl-canvas" width="800" height="600"></canvas>

然后我在第 85 行设置投影:

  • 使用正交投影mat4.ortho(pMatrix, -5, 5, -5, 5, -5, 5);正方形出现在我的 Canvas 上

    <
  • 当我使用透视图时 mat4.perspective(pMatrix, Math.PI/3, 1, -10, 10); 它不起作用

我已经尝试了几个参数

最佳答案

首先,通常您会将 zNear 和 zFar 设为正数。它们代表相机前面的区域如何可见。其次是因为您的 uvMatrix 是您的对象在原点处的单位矩阵。 View 也在原点(参见camerasperspective)

这意味着为了查看对象,您需要将对象移离相机或添加 View 矩阵(这也有效地将对象移离原点)

我将代码更改为这个并且它有效

// set zNear to 0.1
mat4.perspective(pMatrix, Math.PI/3, 1, 0.1, 10);

// move the object out from the camera
mat4.translate(uvMatrix, uvMatrix, [0, 0, -5]);

var canvas;
var gl;

var shaderProgram;

// Vertex Shader
var positionLocation;
var uvMatrixLocation;
var pMatrixLocation;

var uvMatrix = mat4.create();
var pMatrix = mat4.create();

// Fragment Shader
var colorLocation;

var buffer = [];


function initGL() {
  canvas = document.getElementById("webgl-canvas");
  gl = WebGLUtils.setupWebGL(canvas);
  gl.viewportWidth = canvas.width;
  gl.viewportHeight = canvas.height;
}

function createShader(gl, id, type) {
  var shader;
  var shaderSrc = document.getElementById(id);

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

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

  return shader;
}

function initShaders() {

  var fragmentShader = createShader(gl, "fshader", "fragment");
  var vertexShader = createShader(gl, "vshader", "vertex");

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

  // Linka os parametros do shader
  positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
  uvMatrixLocation = gl.getUniformLocation(shaderProgram, "uvMatrix");
  pMatrixLocation = gl.getUniformLocation(shaderProgram, "pMatrix");

  gl.enableVertexAttribArray(positionLocation);

  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Não foi possível inicializar os shaders"); }
}

function initBuffers() {
  createPoly([
    1.0,  1.0,  0.0,
    -1.0,  1.0,  0.0,
    1.0, -1.0,  0.0,
    -1.0, -1.0,  0.0
  ]);
}

function draw() {
  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.useProgram(shaderProgram);

  mat4.perspective(pMatrix, Math.PI/3, 1, 0.1, 10);
  mat4.translate(uvMatrix, uvMatrix, [0, 0, -5]);

  gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix);
  gl.uniformMatrix4fv(uvMatrixLocation, false, uvMatrix);

  buffer.forEach(function(e) {
    gl.bindBuffer(gl.ARRAY_BUFFER, e.buffer);
    gl.vertexAttribPointer(positionLocation, e.vertSize, gl.FLOAT, false, 0, 0);
    gl.drawArrays(e.primtype, 0, e.nVerts());
  });

}

window.onload = function() {
  initGL();
  initShaders();
  initBuffers();  
  draw();
}

// ---------------------------------------------------------------
// --------------------------- Utils -----------------------------
// ---------------------------------------------------------------

function createPoly(vertices) {
  var vertexBuffer;
  vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  var poly = {
    buffer:     vertexBuffer,
    vertSize:   3,
    nVerts:     function() { return vertices.length/this.vertSize; },
    primtype:   gl.TRIANGLE_STRIP
  };

  buffer.push(poly);
}
<script src="https://www.khronos.org/registry/webgl/sdk/demos/common/webgl-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>

<script id="vshader" type="x-shader/x-vertex">
attribute vec3 a_position;

uniform mat4 uvMatrix;
uniform mat4 pMatrix;

varying vec4 v_color;

void main() {
  gl_Position = pMatrix * uvMatrix * vec4(a_position, 1);
  v_color = gl_Position;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
</script>
<canvas id="webgl-canvas" width="800" height="600"></canvas>

关于javascript - 透视投影什么也没显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36099877/

相关文章:

javascript - Three.js 为 faceColors 和 vertexColors 重用几何体

javascript - WebGL 纹理调整大小意外输出

javascript - WebGL 模板缓冲区仅适用于 Firefox

webgl - 使用 WebGL 渲染全屏四边形

javascript - 警告 : There is another module with an equal name when case is ignored

javascript - 当我在 jquery 和 ajax 中的第一个文本框中键入内容时,如何自动填充另一个文本框

javascript - IE 上不显示按钮

opengl-es - WebGL 着色器 : maximum number of varying variables

javascript - 在 Opencart 中实现不同的 disqus 短名称

javascript - key 生成将算法作为错误抛出