博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初涉WebGL
阅读量:6379 次
发布时间:2019-06-23

本文共 4414 字,大约阅读时间需要 14 分钟。

之前一直在捣鼓Vue和React栈,对组件化架构项目有了些理解和体会。今天尝尝WebGL,当然,并不打算现在深入,只是略作了解,我知道这个坑很深。

js的图形库、3d库也有好几款比较流行的,如游戏开发方面的three.js、数据可视化的图表库echarts.js、GIS方面的百度地图、google地图等,最近打算学习下。

言归正传,以前学canvas的时候,只是简单地学习2d context的一些api写写画画,webGL显然更高级些,在MDN文档的介绍中:

 enables web content to use an API based on  2.0 to perform 3D rendering in an HTML  in browsers that support it without the use of plug-ins. WebGL programs consist of control code written in JavaScript and special effects code(shader code) that is executed on a computer's Graphics Processing Unit (GPU). WebGL elements can be mixed with other HTML elements and composited with other parts of the page or page background.

提到了WebGL可以让网页内容中的canvas元素实现3d渲染,其编程由两部分组成,一部分是由js写的控制代码,一部分是在用户设备gpu上执行的实现特定效果的代码(GLSL,注意,GLSL是一门针对GPU的编程语言)。不过WebGL只兼容IE11+

教程假设我们会一些基本的3d图像的概念。这篇入门教程指出,需要我们会一点html和css知识,以及较深的js功底,能理解闭包、原型链、构造函数等概念。

 

 

第一步,检测设备是否支持WebGL:

function detectWebGLContext () {    // Create canvas element. The canvas is not added to the    // document itself, so it is never displayed in the    // browser window.    var canvas = document.createElement("canvas");    // Get WebGLRenderingContext from canvas element.    var gl = canvas.getContext("webgl")      || canvas.getContext("experimental-webgl");    // Report the result.    if (gl && gl instanceof WebGLRenderingContext) {      paragraph.innerHTML =        "Congratulations! Your browser supports WebGL.";    } else {      paragraph.innerHTML = "Failed to get WebGL context. "        + "Your browser or device may not support WebGL.";    }  }
View Code

跟一般的功能检测一样,其实就是判断  gl = canvas.getContext("webgl")|| canvas.getContext("experimental-webgl")  是不是 WebGLRenderingContext 的一个实例。一旦我们的canvas元素有这个rendering context,我们就可以使用它的api进行渲染。

 

第二步,开始简单的example

 

-----填充WebGLContext

1.获取(set up) ,就是上一步的gl。

2.然后drawing buffer(现在先理解为画布)填充颜色。这个过程分两步:

//确定渲染的范围gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);  //设定WebGL的内部状态--设定颜色  // Set the clear color to darkish green.  gl.clearColor(0.0, 0.5, 0.0, 1.0);  //输出其状态--填充颜色  // Clear the context with the newly set color. This is  // the function call that actually does the drawing.  gl.clear(gl.COLOR_BUFFER_BIT);
View Code

 gl.viewport()中前两个参数是相对于左下角的距离。后两个是宽,高。

在定义了drawing buffer的 范围后,我们执行了两个动作,先是设定WebGL的内部状态(颜色为绿色),然后执行语句让drawing buffer 变成WebGL内部状态所设定的样子。所以,WebGL实际上是一个状态机。我们可以回想下,在getContext(“2d”)的时候,要画一个矩形,我们也是遵循同样的操作步骤:

//定义样式(即内部状态)cxt.fillStyle="#FF0000";//输出图形(将样式状态输出到画布中)cxt.fillRect(0,0,150,75);

最后,WebGL中颜色定义都是使用RGBA格式的。

 

-----开始将WebGL和用户交互结合

一例由上面的简单例子延伸而来,对canvas和button绑定了click事件,触发switchColor函数。

该函数先判断是否支持WebGL,再确定画布的范围,之后再执行三行代码:

//产生随机颜色    // Get a random color value using a helper function.    var color = getRandomColor();    //设置WebGL内部状态的颜色新值    // Set the clear color to the random color.    gl.clearColor(color[0], color[1], color[2], 1.0);    //将新值输出到画布    // Clear the context with the newly set color. This is    // the function call that actually does the drawing.    gl.clear(gl.COLOR_BUFFER_BIT);
View Code

----裁剪:

//开启裁剪功能  // Enable scissoring operation and define the position and  // size of the scissoring area.  gl.enable(gl.SCISSOR_TEST);  //设定可更新的区域  gl.scissor(60, 60, 60, 130);  // Clear the drawing buffer solid yellow.  gl.clearColor(1.0, 0.6, 0.0, .1);  gl.clear(gl.COLOR_BUFFER_BIT);
View Code

getContext("2d")中也有相似的api。只有在指定的区域中画布才会被更新(显示)。

----不设置高宽会导致不符合预期的渲染结果

我们知道设置css可以改变元素的视觉高宽,canvas也一样。但如果我们只是单纯设置了css样式,不对其dom节点设置高宽,将导致诡异的渲染效果。

其实不止“webgl”的RenderingConext,“2d”的context也会有这种情况。

以前研究过canvas这个问题,因为css只是改变canvas元素呈现在页面上的视觉大小,但是其逻辑像素默认是300*150.

当我们调用api时,往api中传入表示高宽或x、y轴位置的参数时,一旦超出y轴方向的150和x轴方向的300,就会超出画布。

所以必要的时候,我们得获取canvas节点,然后js设定其逻辑高宽。canvas.height=xx;canvas.width=xx;

 

----封装WebGL 方法

function getRenderingContext() {  var canvas = document.querySelector("canvas");  canvas.width = canvas.clientWidth;  canvas.height = canvas.clientHeight;  var gl = canvas.getContext("webgl")    || canvas.getContext("experimental-webgl");  if (!gl) {    var paragraph = document.querySelector("p");    paragraph.innerHTML = "Failed to get WebGL context."      + "Your browser or device may not support WebGL.";    return null;  }  gl.viewport(0, 0,    gl.drawingBufferWidth, gl.drawingBufferHeight);  gl.clearColor(0.0, 0.0, 0.0, 1.0);  gl.clear(gl.COLOR_BUFFER_BIT);  return gl;}
View Code

这一节没什么新内容,只是把几个基本的语句进行封装。函数做了两件事情,判断是否支持webgl,然后将画布填充成黑色并返回RenderingContext这个接口。

 //日后补充

转载于:https://www.cnblogs.com/alan2kat/p/7837653.html

你可能感兴趣的文章
实战:RHEL6配置dhcp服务器并绑定主机IP
查看>>
百度不收录原因分析——Spider抓取篇
查看>>
Ubuntu Server 上安装 Jexus
查看>>
浏览器渲染原理及解剖浏览器内部工作原理
查看>>
dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
查看>>
Spring Boot项目配置RabbitMQ集群
查看>>
bash 交互与非交互
查看>>
怎么提高自身技术
查看>>
北京游泳馆
查看>>
Mac 安卓模拟器打开 ONS
查看>>
完全卸载Oracle 11g教程
查看>>
Oracle调整表空间大小——ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
查看>>
二叉树(一)
查看>>
函数的递归
查看>>
JavaScript之将JS代码放在什么位置最合适
查看>>
【“零起点”--百度地图手机SDK】如何使用离线地图?
查看>>
深拷贝与浅拷贝复习
查看>>
各种参数的响应时间
查看>>
SQL Server 索引重建脚本
查看>>
23:LVS客户端配置脚本案例
查看>>