透视投影不显示任何内容

Perspective projection showing nothing

本文关键字:任何内 显示 透视投影      更新时间:2023-09-26

我正在尝试遵循 WebGLFundamentals.org 和LearningWebGL教程,并达到了投影部分。

我创建我的场景类似于LearningWebGL教程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);正方形出现在我的画布上

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

我已经尝试了几个参数

首先,通常你会做zNear和zFar正数。它们表示摄像机前方的可见区域。其次,因为你的uvMatrix是你的对象在原点的单位矩阵。视图也在原点(请参阅相机和透视)

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

我将代码更改为此代码,它有效

// 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>

将 zNear 更改为一个小的正数。