WebGL编程指南案例解析之3D视图视区问题
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' +
'uniform mat4 u_MvpMatrix;\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' +
' gl_Position = u_MvpMatrix * a_Position;\n' +
' v_Color = a_Color;\n' +
'}\n'; // Fragment shader program
var FSHADER_SOURCE =
'#ifdef GL_ES\n' +
'precision mediump float;\n' +
'#endif\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' +
' gl_FragColor = v_Color;\n' +
'}\n'; function main() {
// Retrieve <canvas> element
var canvas = document.getElementById('webgl'); // Get the rendering context for WebGL
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
} // Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
} // Set the vertex coordinates and color (the blue triangle is in the front)
var n = initVertexBuffers(gl);
if (n < ) {
console.log('Failed to set the vertex information');
return;
} // Specify the color for clearing <canvas>
gl.clearColor(, , , );
②
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//开启深度检测(基于Z轴,前面的自动遮住后面的,这样不用在意图形先后绘制决定层级的问题)
gl.enable(gl.DEPTH_TEST);
//开启多边形偏移解决不同物体Z轴值一样的问题(基于所在面与视区的角度设置z轴偏移量)
gl.enable(gl.POLYGON_OFFSET_FILL); // Get the storage location of u_MvpMatrix
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
if (!u_MvpMatrix) {
console.log('Failed to get the storage location of u_MvpMatrix');
return;
} var modelMatrix = new Matrix4(); // Model matrix
var viewMatrix = new Matrix4(); // View matrix
var projMatrix = new Matrix4(); // Projection matrix
var mvpMatrix = new Matrix4(); // Model view projection matrix ①
//模型矩阵,用于计算模型的运动(平移、旋转、缩放)
modelMatrix.setTranslate(0.75, , );
//视图矩阵(人看物体的位置)
viewMatrix.setLookAt(, , , , , -, , , );
//透视投影矩阵(相对应的还有正视投影,但是3D下一般用透视投影,看起来更符合人类视角)
projMatrix.setPerspective(, canvas.width/canvas.height, , );
//上述三种矩阵相乘
mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas>
gl.drawArrays(gl.TRIANGLES, , n); // Draw the triangles ③
//绘制之前设置多边形偏移参数值
gl.polygonOffset(1.0, 1.0); //几何体位置移动再画一次(放到右边)
modelMatrix.setTranslate(-0.75, , );
mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
gl.drawArrays(gl.TRIANGLES, , n); // Draw the triangles
} function initVertexBuffers(gl) {
④
var verticesColors = new Float32Array([
// Vertex coordinates and color
0.0, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one
-0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
0.5, -1.0, -4.0, 1.0, 0.4, 0.4, 0.0, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one
-0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
0.5, -1.0, -2.0, 1.0, 0.4, 0.4, 0.0, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one
-0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
]);
var n = ; // Create a buffer object
var vertexColorBuffer = gl.createBuffer();
if (!vertexColorBuffer) {
console.log('Failed to create the buffer object');
return -;
} // Write the vertex information and enable it
gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW); var FSIZE = verticesColors.BYTES_PER_ELEMENT; var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if(a_Position < ) {
console.log('Failed to get the storage location of a_Position');
return -;
}
gl.vertexAttribPointer(a_Position, , gl.FLOAT, false, FSIZE * , );
gl.enableVertexAttribArray(a_Position); var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
if(a_Color < ) {
console.log('Failed to get the storage location of a_Color');
return -;
}
gl.vertexAttribPointer(a_Color, , gl.FLOAT, false, FSIZE * , FSIZE * );
gl.enableVertexAttribArray(a_Color); return n;
}
注意点:
①通过矩阵处理position
模型矩阵:物体的运动(平移、旋转、缩放);
视图矩阵:设置人的视角,也就是第一人称视角;
透视投影矩阵:处理物体的远近,远的物体小,近的物体大;
②开启隐藏面消除
因为webgl渲染的图形的时候,同一个像素点上,后一个绘制的会把前一个绘制的遮盖;
开启隐藏面消除之后,不用担心这个顺序问题,将由Z轴值决定谁应该被隐藏(遮住);
③开启多边形偏移
当不同物体处于同一平面Z轴相同时,就会出现深度冲突,使得物体表面看上去斑斑驳驳的;
开启多边形偏移之后,会根据物体所在的面和视角所形成的夹角生成一个偏移量附加在物体Z轴参数上,从而解决深度冲突;
绘制图形前要设置多边形偏移参数值。
④图形变形问题
在正视投影的视角下,可视区如果比图形高度小的话,图片就会被压缩

WebGL编程指南案例解析之3D视图视区问题的更多相关文章
- WebGL编程指南案例解析之绘制一个点
<!DOCTYPE html> <html> <head> <title>webgl</title> <style type=&quo ...
- WebGL编程指南案例解析之平移和旋转的矩阵实现
手写各种矩阵: //矩阵 var vShader = ` attribute vec4 a_Position; uniform mat4 u_xformMatrix; void main(){ gl_ ...
- WebGL编程指南案例解析之绘制三个点
//案例2.绘制3个点,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //着色器将对这些顶点进行逐个解析, //第一个顶点给到顶点着色器,赋值给 ...
- WebGL编程指南案例解析之绘制四边形
//案例4,绘制矩形,和三角形类似,但是注意因为一个矩形有4个顶点,按照两个三角形绘制矩形的话,顶点顺序要注意 var vShader = ` attribute vec4 a_Position; v ...
- WebGL编程指南案例解析之绘制三角形
//案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...
- WebGL编程指南案例解析之纹理叠加
var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...
- WebGL编程指南案例解析之加载纹理(贴图)
var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...
- WebGL编程指南案例解析之多数据存储于一个缓冲区以及着色器通信
//顶点着色器往片元着色器传值 //多个参数值存于一个缓冲对象中 var vShader = ` attribute vec4 a_Position; attribute float a_PointS ...
- WebGL编程指南案例解析之平移和旋转的math库实现
这里说的math库实现,指的是,通过一般的加减乘除(角度计算)来更新坐标值. 因为涉及到坐标的变化,所以这里都是基于对顶点着色器的修改 平移: var vShader = ` attribute ve ...
随机推荐
- HDU 3549 Flow Problem(最大流模板)
http://acm.hdu.edu.cn/showproblem.php?pid=3549 刚接触网络流,感觉有点难啊,只好先拿几道基础的模板题来练练手. 最大流的模板题. #include< ...
- shell 截取字符串
vvar='{"floor":2,"hotelid":"3433bbb"}' #vvar='{"hotelid":&qu ...
- API接口自动化之2 处理http请求的返回体,对返回体做校验
举例一个接口测试的常见流程 1) 发送接口请求2) 断言接口响应状态是不是200 OK3) 断言接口的响应时间低于某一个值(看情况,不是必选)4) 断言响应数据是否正确,一般的做法是判断某一个值是否相 ...
- 使用tk.mybatis快速开发curd
使用mybatis已经是可以快速开发程序了,对于单表的curd似乎是一种可抽象的结果,下面介绍tk.mybatis的使用方式. maven引用 我使用的是这个版本,所以相关功能介绍也是这个版本. 使用 ...
- 理解Fragment的生命周期
与活动类似,Fragment也有自己的生命周期.理解Fragment的生命周期有助于在Fragment销毁时能恰当地保存其实例,然后在重新创建时能够将其恢复至之前的状态. 下面的“试一试”将研究Fra ...
- Shell循环输入符合条件为止
提供用户输入,直到输入d/D/r/R为止. #!/bin/bash ]; do echo -n "(D)ebug or (R)elease?" read select_build_ ...
- 图片保存到数据库以及C#读取图片
图片保存到数据库,如果是sqlserver就是Image类型,如果保存到Oracle就是blob类型,在c#中相对应的就是byte[]类型,同时只需要对读出的数据强制转换就行(byte[])objec ...
- [.NET开发] C# 如何创建Excel多级分组
要设置显示或者隐藏分类数据下的详细信息,在便于数据查看.管理的同时也使文档更具美观性.那么,在C#中如何来创建Excel数据的多级分组显示呢?下面将进行详细阐述.方法中使用了免费版组件Free Spi ...
- Confluence 6 为 Active Directory 配置一个 SSL 连接预要求
希望生成证书,你需要安装下面的组件在你希望连接的 Windows Domain Controller 上. Internet Information Services (IIS) 在你安装 Windo ...
- VS2013/2015 html 设计视图窗口