WebGL减面交互程序 小记
Posted 坏打印机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebGL减面交互程序 小记相关的知识,希望对你有一定的参考价值。
记录一个实现局部低面交互、顶点动画的效果,不想看编程解决问题艰辛历程的同学,可以直接点击:http://simplifymodeldemo.farbox.com/ 或者文尾[阅读全文]跳转到最终的效果网页。
这是最终的交互效果:
用Three.js实现模型低面化,其实在Three.js的examples\js\modifiers文件夹里,已经有一个叫做 [ SimplifyModifier.js ] 的工具。然而它每次返回一个新的低面化过的Geometry,没办法实现局部交互、顶点动画的效果。
因此,改造这个轮子看起来像是最简便的途径实现我要的效果。
一、减面算法简介:
减面算法理解起来不难,有一点线性代数向量运算基础,都看得懂,大概分为几步:
①、首先计算每个顶点的最小collapseCost和collapseNeighbor,collapseNeighbor表示该顶点移动的相邻顶点,collapseCost则表示该顶点移动后,对整个模型的形状造成的影响大小。
这里值得一提的是collapseCost的计算,SimplifyModifier.js里,是用computeEdgeCollapseCost( u, v )来运算的。这个collapseCost由两个因子相乘得来。一个是uv的距离dist,一个是uv共边的面的法向量,乘以以u为顶点的面的法向量,做两个嵌套的for循环,得出最大的影响因子。
②、遍历所有的顶点,找出最小collapseCost的顶点,对它进行坍塌。
③、循环②,一直到坍塌了指定的数量。
④、返回一个新的几何体。
(为了防止字太多插张图。
二、Three.js 的一个坑:
Three.js里面有BufferGeometry和Geometry,这两个可以互相转换。
在调用减面算法之后,得到的是一个Geometry类型的对象,因为我需要给模型对象设置references的attribute,因此我需要转换成BufferGeometry类型。问题就出在调用
new THREE.BufferGeometry().fromGeometry( foGeo )
之后,展示出来的模型的顶点全瞎几把连面,一度奔溃。
于是打开BufferGeometry.js看下fromGeometry函数的源代码,发现它是通过一个DirectGeometry的中间对象来转换的。
于是再打开DirectGeometry.js看看,一看才发现为什么叫做[ DirectGeometry ](微笑脸),直接丢弃了所有indices的信息,本来可以用索引模式标记面,统统不要,统统不要,全部换成重复的点来记录。
在github上看到有人对这个提出质疑,Three.js的作者是这么回复的。大概的意思是的确是把索引信息全部丢弃,需要更多的例子让他觉得保留索引信息是必要的。然后因为自己也不确定DirectGeometry的必要性,因此也没写入doc。
三、改造SimplifyModifier.js:
改造SimplifyModifier.js,主要是得在顶点之间加入父子级关系。
不同于原来的SimplifyModifier,我没有在坍塌过程删除点和面。而是当u坍塌到v的时候,把u的父级设置为v,并把u以及u的所有子级的位置挪动v的位置。
谨防父子级循环!
最后SimplifyModifier返回的不是一个新的几何体,而是顶点之间的父子级关系。
因为Geometry转BufferGeometry的过程会丢失顶点索引数据,增加点数量。所以我给BufferGeometry的设置reference属性的时候,也按照Geometry转DirectGeometry的时候,遍历面处理点的顺序,添加reference。
四、顶点动画实现:
这里还是用到自定义着色器实现,并且需要一个离屏WebGL渲染来计算顶点的位置。
在离屏渲染的时候,需要把带顶点初始位置信息的texture和父子级关系信息的texture传入,然后判断顶点是否在交互球范围内。若在,则索引父级的currentPos,向它挪去。
离屏渲染的target是currentPosition,它将传入bufferGeometry的自定义顶点着色器中,设置顶点位置。
这其实是WebGL粒子渲染的老套路了,用自定义着色器,可以实现各种交互效果,偏题一下,如下两种。
终于在睡前撸完了小记,把这个曾经的TODO翻篇了。明天可以好好弄下毕设。
这么晚了还有人在不!晚安。
点击阅读全文体验demo。处理模型需要4-8s,请耐心等候哈。
以上是关于WebGL减面交互程序 小记的主要内容,如果未能解决你的问题,请参考以下文章