透视投影显示什么

时间:2016-03-19 09:07:21

标签: 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>
&#13;
&#13;
&#13;

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

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

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

我已经尝试了几个参数

2 个答案:

答案 0 :(得分:1)

首先,您通常会生成zNear和zFar正数。它们代表了相机前面区域的可见性。其次是因为你的uvMatrix是你的对象的身份矩阵。该视图也位于原点(请参阅camerasperspective

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

我将代码更改为此并且有效

// 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]);

&#13;
&#13;
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);
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

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