CommentCoreLibrary icon indicating copy to clipboard operation
CommentCoreLibrary copied to clipboard

用 webgl 实现弹幕可以不?

Open nareix opened this issue 9 years ago • 10 comments

会有什么坑?

nareix avatar May 12 '16 09:05 nareix

感觉理论上是可以的,之前曾经考虑过,CCL也预留了支持Canvas的能力。踩到的最大的两个坑是:

  • 文字布局: WebGL/OpenGLES 2.0没有任何的文字显示能力(参考:http://delphic.me.uk/webgltext.html ),所以就只有把它搞到Canvas里然后当 Texture 或者写一些高端的 Shader 送给 WebGL当图片或者渲染逻辑渲染。其实这里引发的诸如 bitmap 被拉扯的问题、字体没有办法经过系统的文字引擎(Anti-Aliasing、LCD优化等等)所以看起来非常渣,就已经比较坑了。

    还有个更难解决的问题(包括在纯2D Canvas 版也是)就是文字布局。基于Canvas的2D绘图都是没有文字布局能力的,所以要手动处理诸如换行和文字高度等问题。现在 Canvas context 2d 不提供度量文字 高度 的API (http://stackoverflow.com/questions/1134586/how-can-you-find-the-height-of-text-on-an-html-canvas )然后现在的 hack 都是基于英语的,或者基于先当DOM测量。而且最靠谱的(逻辑上)度量方法就是:先渲染出来,然后去手动检查像素到底最高/最低填到哪里了。

    所以当考虑到弹幕是CJK字体和西文字体混杂、有可能有Emoji、高级弹幕作者还能定义字体的这些问题,于其自己实现一个文字渲染引擎(虽然并不是不可能)就不如利用浏览器自创始就具有的最基本的能力(排布并渲染文字)要方便了。

  • 设备兼容性: 并不是所有的设备都支持WebGL+安全策略现在版本的WebGL还没有很好的定义(于是有的浏览器故意不支持),不得不有个Fallback模式。然后就变成写两个弹幕系统了2333。

    虽然WebGL比Flash之类的开放了很多吧,但是万一BUG了,就也是一样什么都不显示的空白,没有很好的回退(不像,比如,CSS/HTML还是会尽力渲染自己理解的部分的,CCL早期甚至都能再IE6上跑)。

基于Canvas的弹幕引擎尝试性实现好像在Github上有好多(虽然,目前看排布算法大部分普遍都比较坑),个人见过这个https://github.com/iTisso/DanmuPlayer 完成度还是很高的(虽然有整个一个库去搞Canvas操作)。CCL理论上也可以支持Canvas(需要写一个新的弹幕类,extend CoreComment)。

参考:目前B站的HTML5弹幕回退是基于HTML+CSS3的,A站的播放器(如果没换的话)用得就是CCL。。。

jabbany avatar May 12 '16 10:05 jabbany

@jabbany 赞分析!

那 webgl 的唯一优点是比较快?

nareix avatar May 12 '16 10:05 nareix

WebGL主要是搞3D的,所以大概优势在于高级弹幕支持?Canvas的优势在于浪费的overhead比较低,毕竟在直接画位图。当然、现当今DOM也是硬件加速的,所以目前CCL最大的性能问题就是 DOM元素的添加和去除(会改DOM树所以是个Blocking操作),其次的性能问题是因为懒没好好写定时器(这个在 dev-cssonly分支通过不再用定时器直接用CSS3动画一部分被解决了)。

jabbany avatar May 12 '16 10:05 jabbany

我记得最耗时间的函数还是获取宽度和高度啊~

On Thu, May 12, 2016, 6:33 PM Jim Chen [email protected] wrote:

WebGL主要是搞3D的,所以大概优势在于高级弹幕支持?Canvas的优势在于浪费的overhead比较低,毕竟在直接画位图。当然、现当今DOM也是硬件加速的,所以目前CCL最大的性能问题就是 DOM元素的添加和去除(会改DOM树所以是个Blocking操作),其次的性能问题是因为懒没好好写定时器(这个在 dev-cssonly分支通过不再用定时器直接用CSS3动画一部分被解决了)。

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/jabbany/CommentCoreLibrary/issues/56#issuecomment-218720186

Catofes avatar May 12 '16 11:05 Catofes

@Catofes 好吧,准确说其实是因为DOM宽度高度计算是lazy的(插入后只有读才会导致去计算),但是意思差不多。就是有绕不过去的基于DOM的blocking操作。

jabbany avatar May 12 '16 12:05 jabbany

换行其实不需要处理吧,弹幕都是单行的; 弹幕高度个人的处理方案是手动输入,当fillStyle = xemheight = 100 * x……

zsxsoft avatar May 14 '16 13:05 zsxsoft

怎么说呢。。。这样做能解决一些情况,但是不是一个靠谱的解决方案。。。有点像是hardcode了字体的高度想对位点高度的比例值。

之前的讨论参考 #26 和 jabbany/ABPlayerHTML5#3 (这个很长)

jabbany avatar May 14 '16 16:05 jabbany

嗯……项目需求不同,问题的解决难度也不同……毕竟我压根不需要支持各种高级弹幕 看了这两个讨论,我发现我遇到的Canvas渲染弹幕的坑竟然都已经几年了啊……而且我做的还仅仅是针对单一内核的东西而已……

zsxsoft avatar May 14 '16 16:05 zsxsoft

弹幕的坑深得不得了23333。。。 当年CCL只是高中无聊的时候写的小玩具23333

jabbany avatar May 14 '16 16:05 jabbany

  1. Layout!Layout!
  2. 边缘模式下绘制的字体和普通模式下的本体边界并不对齐。
  3. 字体边缘像素透明度信息丢失。

关于第一点现在以pt为单位近似计算文字高度,效果还不错(中英文),应该是因为字体还算规整吧。

第二点和第三点……想办法ing。我现在的方案是canvas绘制文字后作为纹理绘制到上下文,因而有这两个问题。

唉,此issue出现各种高中大神……

hozuki avatar Jun 12 '16 12:06 hozuki