Bulletproof 的当前状态

一直都没回复tt和jabbany,对不起了。

距离上一次 Bulletproof 的代码推送已经超过了一个月。不知star了的各位大神还有多少仍然在关注。这半个月来无声息也是我的问题,不过最近是艰难的一段时间,接下来两个多月也会是。趁着今天还有点时间简要说一下 Bulletproof 的 WebGL 化进度。一些示例截图&目前的问题。

填充选用的是 libtess。虽说正如tt提到的,Pixi 采用 earcut 而我们用 libtess,后者能处理更多东西(例如相交处理)不过效率降低,但是目前还没观察到足够复杂的填充环境(虽说以后可能会有)。

现在已经能运行三个基础示例:

3D球示例

绿坝娘示例

小圆脸示例

可以见到,目前还有如下缺陷:

  1. 锯齿!锯齿!锯齿!默认的抗锯齿不能用,而且可能是我没调好 WebGLRenderingContext 的设置,透明度有问题(下面还会提到),导致 FXAA 滤镜效果很差。
  2. DisplayObject 的滤镜没开。按照目前的试验,BlurFilter 似乎是可以用的,GlowFilter 还待调试。开了滤镜后帧率有较大幅度下降。
  3. 绿坝娘的裙子缺了一块。估计不是脚本的问题,而是我的代码里漏了什么吧。

外表之下的问题:

  1. 所有的临时 WebGLRenderTarget 都是频繁创建、销毁的,造成较大的开销。
  2. ShaderBaseWebGLRenderTarget 绑定,这影响了 WebGLRenderTarget 的分配策略,和滤镜的多次处理策略,要学习 Pixi 的方法。
  3. 填充和画线逻辑还有点问题(下面会详细讲)。

下面是测试 libtess 计算结果的代码。(默认 winding rule 为 ODD

tt-2 示例

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();

tt-2 示例,Flash 标准

 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.4 时的输出

根本看不出来对么?不过确实填充了,切换到 alpha0.8 时:

alpha = 0.8 时的输出

如果靠近屏幕,勉强能看到一点。0.9 时再明显一点,1.0 就直接变成纯色了。所以目前我还不清楚是什么导致了这个 alpha 变化与预期不符的问题。标准输出应该如下:

Flash 下 alpha = 0.4 时的输出

alpha 直接影响了 FXAA 的结果。我们这里弄得源图像(有大量透明空白区域)的 alpha 全是 1.0 一样,计算半透明时透明的点都当成纯黑点了。要不你看人家示例多正常……

更复杂的示例也有准备,不过也只是部分正确,moveTo() 的处理和 closePath() 的处理要改。

测试5

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();

测试5,Flash 标准

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 到的软件了。我还是很怀念原来的感觉,所以我想做一些自己能认同的东西(村长语:你不要总是批评别人啊,你见到哪个批评家被历史记住的),仅此而已。所以为了摆脱目前的环境,我需要做出合理的牺牲。

关于惊叹的历史,有时间再说。(好像以前几个说“有时间再说”的文章都没写下去了……)

分享到 评论