今天总结记录一下WebGL中主循环的创建和作用。我先说明什么是主循环,其实单纯的webgl不存在主循环这个概念,这个概念是由渲染引擎引入的,主循环就是利用一个死循环或无截止条件的递归达到定时刷新canvas场景的函数,也就是人们常说的canvas刷新率(fps)。在讨论主循环的用处之前,我们先明确一下一个简单的完整webgl的渲染过程是怎样的,请看下图。

好了我们通过上图看到一个mesh完整的渲染流程,大致再讲解一下,首先如果是持续绘制模型的话,就不要gl.clear(gl.color_buffer_bit),否则会将之前绘制进canvas场景的模型擦除,这也是我们所不希望看到的。还是老样子,向vertex-shader中传入attribute和uniform参数,然后调用gl.drawElement进行一次绘制。这个流程已经很清楚了,如果还有问题,请看之前的博客,链接地址https://www.cnblogs.com/ccentry/p/9864847.html。到这里我们把一次绘制渲染的流程重新理了一遍,接下来我们再把场景树的流程理清楚,请看下图。

我们可以看到,每次我们遍历到一个树节点,我们就会检查这个节点使用的shader是哪一对vertex-shader和fragment-shader,然后调用之前图示的渲染流程,绑定shader;接下来检查该节点相对于其父节点的空间变换矩阵matrixTransform,经过运算传给shader的uniform;随后检查mesh,传给shader的attribute;最后检查材质和UV这类参数,传给shader。最后所有传值都结束以后,drawElement将该节点模型绘制到canvas场景中去。直到遍历玩整棵树,将所有模型都绘制进canvas场景,才是完整的一帧渲染流程。

  以上是复习之前2篇文章讨论的内容,也理了一遍整个渲染流程。接下来我们进入今天要讨论的主题,即webGL制作的渲染引擎的主循环。文章开头说过了,主循环就是一个无限循环的函数,在这个函数中我们要做的就是重复刚才我们渲染整个scene场景的过程。具体的循环间隔可以人为的去设置,例如通过setTimeout来设施循环时间间隔,即设置每次重新渲染的时间间隔。这么做有什么好处吗,当然有。我之前做的demo就没有主循环的概念,纯粹是鼠标事件触发的重新绘制,即clear(擦除)->traverseNodeTree(遍历树)->buffer(传参)->draw(绘制)->traverseNodeTree->buffer->draw ......->traverseEnd(遍历结束)。每次这个过程都是计算鼠标的clientXY来重绘,由mouseUp事件触发。其实就是一个静态模仿动态的过程。这么做当然也能做出动态交互的效果,没有问题,但主循环给了我们一个更好的交互事件管理模式,即每一帧绘制时间间隔到了的时候,就会检查交互后的模型参数,然后进行重绘。同样也是计算clientXY,就不需要一次次去监听mouseUp事件了。这是我理解的主循环在事件交互里的作用。当然更复杂的交互管理,模型预筛选(超过视棱台的discard或选择不绘制),都可以在主循环里操作。主循环还有制作animation动画的用处,这里不是讨论的重点,所以就暂时不展开讲。

  说了半天,怎么构造WebGL主循环还没说,我们就以Threejs的render渲染流程为依托,来看看render在主循环里是怎么玩的,以及今天要说的window.requestAnimationFrame是怎么用的,请看下面代码。

/**
* 进行渲染
* */
function rend(){
renderer.render(scene, camera);
}
//动效
function animate(){
requestAnimationFrame( animate );
controls.update();
rend();
}
animate();

我们看到这就是一个简单的递归,目的就是利用html5的requestAnimationFrame进行定时重绘。从而达到上面说的鼠标交互效果。
  今天仅仅是初步了解了一下主循环是什么,干什么用的,其应用场景讨论也局限在渲染和鼠标交互上,本人水平有限,希望各位大佬指教,在此贻笑大方。谢谢@山椒@上校已死两位大佬的解释指点,今天就写这些见解,再次感谢。

引用本文请注明出处https://www.cnblogs.com/ccentry/p/9938725.html

WebGL中使用window.requestAnimationFrame创建主循环的更多相关文章

  1. oracle创建主键序列和在ibatis中应用

    oracle创建主键序列 oracle主键序列的查询和ibitas中应用

  2. sql server 中常用修改列 ,创建主外键操作

    表结构 CREATE TABLE [staff] ( [id] [varchar](50) NOT NUL L, [name] [varchar](50) NOT NULL, [password] [ ...

  3. window.requestAnimationFrame

    今天小猪在看一个html5的demo时一直在找他的动画是怎么实现的,按照我的理解就应该是调用setInterval来循环调用动画函数来实现.但是在Demo中就是找不到这个函数.干着急的小猪只好一步一步 ...

  4. 网页性能管理详解:浅谈chrome-Timeline及window.requestAnimationFrame()方法

    你遇到过性能很差的网页吗? 这种网页响应非常缓慢,占用大量的CPU和内存,浏览起来常常有卡顿,页面的动画效果也不流畅. 你会有什么反应?我猜想,大多数用户会关闭这个页面,改为访问其他网站.作为一个开发 ...

  5. sql语句创建主键、外键、索引、绑定默认值

    use Mengyou88_Wuliu --创建公司表 create table dbo.Company2 ( CompanyID ,) not null, CompanyName ) null, A ...

  6. Oracle创建主键自增表

    Oracle创建主键自增表   1.创建表    create table Test_Increase(            userid number(10) NOT NULL primary k ...

  7. oracle建表的时候同时创建主键,外键,注释,约束,索引

    --主键create table emp (id number constraint id_pr primary key ,name1 varchar(8));create table emp9 (i ...

  8. 5.oracle建表的时候同时创建主键,外键,注释,约束,索引

    5.oracle建表的时候同时创建主键,外键,注释,约束,索引 1 --主键 )); ) ,constraint aba_pr primary key(id,name1)); --外键 )); --复 ...

  9. SQLServer之创建主XML索引

    创建主XML索引注意事项 若要创建主 XML 索引,请使用 CREATE INDEX (Transact-SQL) Transact-SQL DDL 语句. XML 索引不完全支持可用于非 XML 索 ...

随机推荐

  1. C/C++结构体字节对齐详解

    结构体的sizeof先看一个结构体:struct S1{    char c;    int i;}; sizeof(S1)在VC6中按默认设置得到的结果为8.我们先看看sizeof的定义——size ...

  2. IntelliJ IDEA SVN无法正常使用问题

    SVN checkout时候会出现错误:Cannot run program "svn" (in directory "E:\Projects"): Creat ...

  3. HDU 3367 (伪森林,克鲁斯卡尔)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=3367 Pseudoforest Time Limit: 10000/5000 MS (Java/Oth ...

  4. ORACLE 中rownum和row_number()的使用区别(可指定取sql结果集的第几个数据)

    这篇文章主要介绍了oracle中rownum和row_number()的使用方法以及区别和联系,十分的详细,有需要的小伙伴可以参考下.   row_number()over(partition by ...

  5. 轻量ORM-SqlRepoEx (十五)最佳实践之数据映射(Map)

    简介:SqlRepoEx是 .Net平台下兼容.NET Standard 2.0人一个轻型的ORM.解决了Lambda转Sql语句这一难题,SqlRepoEx使用的是Lambda表达式,所以,对c#程 ...

  6. center os 7 安装 elasticSeartch

    Centos7下安装配置elasticsearch 6.3.1   1)下载 Elasticsearch 6.3.1 地址:https://artifacts.elastic.co/downloads ...

  7. python IO模式(多路复用和异步IO深入理解)

    1.事件渠道模型.事件渠道为异步IO的原型. 2.IO模式,一次IO调用会经历两个阶段.一.等待数据阶段,将数据从网络或者是磁盘读取到系统内核(kennel) 二.将数据从内核拷贝到进程中. 基于这两 ...

  8. [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...

  9. 4540: [Hnoi2016]序列

    4540: [Hnoi2016]序列 https://www.lydsy.com/JudgeOnline/problem.php?id=4540 分析: 莫队+RMQ+单调栈. 考虑加入一个点后,区间 ...

  10. centos7.4 防火墙设置

    1.关闭默认的firewall防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service ...