Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用 webgl 实现弹幕可以不? #56

Open
nareix opened this issue May 12, 2016 · 10 comments
Open

用 webgl 实现弹幕可以不? #56

nareix opened this issue May 12, 2016 · 10 comments

Comments

@nareix
Copy link

nareix commented May 12, 2016

会有什么坑?

@jabbany
Copy link
Owner

jabbany commented May 12, 2016

感觉理论上是可以的,之前曾经考虑过,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。。。

@nareix
Copy link
Author

nareix commented May 12, 2016

@jabbany 赞分析!

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

@jabbany
Copy link
Owner

jabbany commented May 12, 2016

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

@Catofes
Copy link
Contributor

Catofes commented May 12, 2016

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

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
#56 (comment)

@jabbany
Copy link
Owner

jabbany commented May 12, 2016

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

@zsxsoft
Copy link

zsxsoft commented May 14, 2016

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

@jabbany
Copy link
Owner

jabbany commented May 14, 2016

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

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

@zsxsoft
Copy link

zsxsoft commented May 14, 2016

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

@jabbany
Copy link
Owner

jabbany commented May 14, 2016

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

@hozuki
Copy link

hozuki commented Jun 12, 2016

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

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

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

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

@jabbany jabbany added this to the Improve Rendering Efficiency milestone Apr 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants