一直都没回复tt和jabbany,对不起了。
距离上一次 Bulletproof 的代码推送已经超过了一个月。不知star了的各位大神还有多少仍然在关注。这半个月来无声息也是我的问题,不过最近是艰难的一段时间,接下来两个多月也会是。趁着今天还有点时间简要说一下 Bulletproof 的 WebGL 化进度。一些示例截图&目前的问题。
填充选用的是 libtess。虽说正如tt提到的,Pixi 采用 earcut 而我们用 libtess,后者能处理更多东西(例如相交处理)不过效率降低,但是目前还没观察到足够复杂的填充环境(虽说以后可能会有)。
现在已经能运行三个基础示例:
可以见到,目前还有如下缺陷:
- 锯齿!锯齿!锯齿!默认的抗锯齿不能用,而且可能是我没调好
WebGLRenderingContext
的设置,透明度有问题(下面还会提到),导致 FXAA 滤镜效果很差。 DisplayObject
的滤镜没开。按照目前的试验,BlurFilter
似乎是可以用的,GlowFilter
还待调试。开了滤镜后帧率有较大幅度下降。- 绿坝娘的裙子缺了一块。估计不是脚本的问题,而是我的代码里漏了什么吧。
外表之下的问题:
- 所有的临时
WebGLRenderTarget
都是频繁创建、销毁的,造成较大的开销。 ShaderBase
与WebGLRenderTarget
绑定,这影响了WebGLRenderTarget
的分配策略,和滤镜的多次处理策略,要学习 Pixi 的方法。- 填充和画线逻辑还有点问题(下面会详细讲)。
下面是测试 libtess 计算结果的代码。(默认 winding rule 为 ODD
)
var s = $.createShape({
lifeTime: 7
});
var g = s.graphics;
g.lineStyle(2, 0x00ff00);
g.beginFill(0xff0000, 1);
g.moveTo(100, 100);
g.lineTo(200, 100);
g.lineTo(200, 400);
g.curveTo(350, 125, 300, 400);
g.endFill();
import flash.display.Shape;
import flash.display.Graphics;
import flash.events.Event;
function drawShape (ev) {
var s:Shape = new Shape();
this.stage.addChild(s);
var g:Graphics = s.graphics;
g.beginFill(0, 1.0);
g.drawRect(0, 0, s.width, s.height);
g.endFill();
g.lineStyle(2, 0x00ff00);
g.beginFill(0xff0000, 1);
g.moveTo(100, 100);
g.lineTo(200, 100);
g.lineTo(200, 400);
g.curveTo(350, 125, 300, 400);
g.endFill();
}
this.stage.addEventListener(Event.ENTER_FRAME, drawShape);
你可能要奇怪了,为什么填充的 alpha
选择的是 1.0
呢?因为在 0.4
的时候,二者是这个样子的:
根本看不出来对么?不过确实填充了,切换到 alpha
为 0.8
时:
如果靠近屏幕,勉强能看到一点。0.9
时再明显一点,1.0
就直接变成纯色了。所以目前我还不清楚是什么导致了这个 alpha
变化与预期不符的问题。标准输出应该如下:
alpha
直接影响了 FXAA 的结果。我们这里弄得源图像(有大量透明空白区域)的 alpha
全是 1.0
一样,计算半透明时透明的点都当成纯黑点了。要不你看人家示例多正常……
更复杂的示例也有准备,不过也只是部分正确,moveTo()
的处理和 closePath()
的处理要改。
var s = $.createShape({
lifeTime: 7
});
var g = s.graphics;
g.lineStyle(2, 0x00ff00);
g.beginFill(0xff0000, 1.0);
g.moveTo(100, 100);
g.lineTo(200, 200);
g.lineTo(150, 200);
g.lineTo(150, 120);
g.moveTo(100, 150);
g.lineTo(200, 150);
g.lineTo(200, 170);
g.lineTo(100, 170);
g.lineTo(100, 150);
g.drawCircle(20, 20, 10);
g.lineTo(0, 0);
g.endFill();
import flash.display.Shape;
import flash.display.Graphics;
import flash.events.Event;
function drawShape (ev) {
var s:Shape = new Shape();
this.stage.addChild(s);
var g:Graphics = s.graphics;
g.lineStyle(2, 0x00ff00);
g.beginFill(0xff0000, 1.0);
g.moveTo(100, 100);
g.lineTo(200, 200);
g.lineTo(150, 200);
g.lineTo(150, 120);
g.moveTo(100, 150);
g.lineTo(200, 150);
g.lineTo(200, 170);
g.lineTo(100, 170);
g.lineTo(100, 150);
g.drawCircle(20, 20, 10);
g.lineTo(0, 0);
g.endFill();
}
this.stage.addEventListener(Event.ENTER_FRAME, drawShape);
可能先得保证活命了,课内自己开一个组单挑别的组(5~7人×6),真是作死。不过他们的思想和经验都远远没那么先进,你能想象他们看着10年前的教学示例,由于不知道什么开发技术,就要沿着10年前的老路用 Access + VBA 来开发一个 ERP 系统么?(他们 VBA 也应该会是从视频课程里学的,到最后也只是应用上略知皮毛而已。针对我设计时的方案文本,老师曰:“我们不是做软件工程的,是做应用软件的。”我倒不认为这是采用落后的工具和符合行业风气的丑陋美工的借口。)不过“中国人的集体智慧”可是不可以轻视的……
可能要断断续续拖到第一场之后了……
给了我最大震撼的软件产品有两个,第一个是 Windows XP(尤其是桌上弹球),第二个是 Grand Theft Auto 3。之后就没有能如此将我 shock 到的软件了。我还是很怀念原来的感觉,所以我想做一些自己能认同的东西(村长语:你不要总是批评别人啊,你见到哪个批评家被历史记住的),仅此而已。所以为了摆脱目前的环境,我需要做出合理的牺牲。
关于惊叹的历史,有时间再说。(好像以前几个说“有时间再说”的文章都没写下去了……)