透视投影不显示任何内容
Perspective projection showing nothing
我正在尝试遵循 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 更改为一个小的正数。
相关文章:
- 是否有任何内置方法可以更改JavaScript对象'的属性设置为某个值
- 如何使用 html 类或 id 在任何地方显示内容
- 使用JavaScript(可能是CSS)在HTML5画布内显示特定宽度/高度的完整图像大小(100%宽度/高度)
- 使用 CasperJS 时,是否可以在执行任何内联或外部 Javascript 之前与加载页面的 DOM 进行交互
- 更改文件字段内显示的路径的位置
- 在将图像上传到服务器之前在画布内显示图像
- 在
标签内显示产品名称
- 输入类型“文本”的 ng-init 不会在文本框内显示任何数据
- DHTML - 在有限的时间内显示图片
- 仅在特定区域内显示图像
- 在高图表的 tspan 标签内显示图像
- 使用 javascript 获取仅在日期范围内显示的数据
- 在固定大小的块内显示具有圆角的任意大小的图像
- 循环 JS 变量不会在函数内显示正确的值
- 在酒窝气泡图中的每个气泡内显示标签
- 需要我使用 NodeJS 在页面内显示 OpenLayers 3 映射
- 如何使用离子和角度在模态内显示选定的图像名称
- 使用javascript在if条件内显示链接
- 找不到“”;应用程序“;模板或视图.对象{fullName:“template:application”}将不呈现任何内
- AngulasJS、OnsenUI、Phonegap、警报在控制器内显示两次