Unity WebGL 开发(二)

在前文中,主要写了一些关于 WebGL 发布、调试、以及开发限制等问题,本文主要是关于 WebGL平台中的图形渲染、网络、音频相关的东西,WebGL 是在 OpenGL ES 发展来的,WebGL 1.0 基于 OpenGL ES 2.0,WebGL 2.0 基于 OpenGL ES 3.0,目前主流火狐和 Chrome 已经支持 WebGL 2.0,而 Safari 和 Edge 还不支持 2.0。

渲染相关

Camera Clear

WebGL 在每帧最后都会清除frame buffer,即使 Camera.clearFlags 设置了 DontClear 也不起作用,如果需要改变这种默认行为,可以通过修改发布模板中的 index.html 文件。

1
2
3
4
5
UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%", {
Module: {
"webglContextAttributes": {"preserveDrawingBuffer": true},
}
});

延迟渲染

Unity WebGL 平台只在支持 WebGL 2.0 下支持延迟渲染,WebGL 1.0 将会采用前向渲染。

全局光照

只支持 baked GI,实时 GI 不支持,此外,只支持 Non-Directional光照贴图。

MovieTexture

WebGL 不支持通过 MovieTexture 播放视频,一种替代的方法是,使用 Html5 的视频组件。

字体渲染

WebGL 支持动态字体,但是由于它不能访问本机文件系统,所以使用到的字体文件必须放到项目当中。(包括 Fallback fonts,以及粗体和斜体字体)

为了提高性能,建议在 WebGL 中使用 TMP 来替代默认的 UGUI 文本组件,使用静态字体来替代动态字体。

抗锯齿

绝大部分的浏览器和 GPU 都支持抗锯齿,只需要在 Quality 设置中启用抗锯齿即可,但是在 WebGL 1.0 中存在一些限制:

  • 不能在运行时启用/禁用,必须在系统发布时就确定;
  • 多重采样(multi sampleing 2x、4x…)没有作用,只有开启、关闭两个状态;
  • 如果 Camera 上又任何Post-Processing-Effect,都会引起抗锯齿失效;
  • HDR 和抗锯齿是不兼容的,如果开启抗锯齿,就需要关闭 Camera上的 Allow HDR选项。

WebGL2.0 不存在以上限制。

网络相关

处于安全考虑,JavaScript 没有直接访问 IP 套接字的权限,所以 System.Net 命名空间下的全部类型,System.Net.Sockets 命名空间下的部分类型,在 WebGL 平台是不支持的,同样的还有 UnityEngine.Network* 前缀的类型。

如果需要访问网络,有以下几种选择:

  • 使用WWW
  • 使用UnityWebRequest
  • 使用新的 Unity Networking 模块;
  • 在 JavaScript 中 WebSocket 或 WebRTC。

WWW

在 WebGL 平台,WWWUnityWebRequest都是用 JavaScript 的XMLHttpRequest来实现,通过浏览器来处理 WWW 请求。

假设我们把 WebGL 内容部署在服务器 A,而在运行时,我们需要用 WWW 从另一个服务器 B 下载资源,这就需要 B 服务器通过 CORS 进行授权,如果服务器 B 没有进行 CORS 设置,那么将会在控制台看到如下错误:

1
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://myserver.com/. This can be fixed by moving the resource to the same domain or enabling CORS.

更多 CORS 信息可以参考这里

不要使用阻塞代码

不要是阻塞代码来等待 WWW 或 WebRequest 完成,比如下面代码:

1
while(!www.isDone){}

因为 WebGL 是单线程,而 XMLHttpRequest 又是异步方法,整个一直执行 while 循环,而不能更新 XMLHttpRequest 响应信息,可以使用协程和 yield 来等待下载完成。

WebSocket

在新版 unity 网络模块中,可以设置 Networking.NetworkManager.useWebSockets 来启用 WebSocket 协议。

目前浏览器基本 都支持 WebSocket 和 WebRTC(Safari 不支持),但是Unity 没有公开这两个 API,如果要使用的话,可以使用 JavaScript 插件。

音频相关

与其他平台采用 FMOD 音频引擎不同, WebGL 由于不支持多线程,因此采用基于 WebApi 的音频控制模块,让浏览器来控制音频的混合和播放,因此 WebGL 音频使用存在很多限制,下面列举 WebGL 平台支持的音频功能,如果没有列出,则说明 WebGL 平台不支持该功能。

AudioSource

支持属性:

  • clip
  • dopplerLevel
  • ignoreListenerPause
  • ignoreListenerVolume
  • isPlaying
  • loop
  • maxDistance
  • minDistance
  • mute
  • pitch (只支持正值)
  • playOnAwake
  • rolloffMode
  • time
  • timeSamples
  • velocityUpdateMode
  • volume

支持函数:

  • Pause
  • Play
  • PlayDelayed
  • PlayOneShot
  • PlayScheduled
  • SetScheduledEndTime
  • SetScheduledStartTime
  • Stop
  • UnPause
  • PlayClipAtPoint

AudioListener

所有的 API 都支持

AudioClip

WebGL 总是将音频剪辑压缩格式设置为 ACC,因为该格式在浏览器支持比较广泛。

支持的属性:

  • length
  • loadState
  • samples

支持的方法:

  • AudioClip.Create :部分支持,传递给该方法的 stream 参数必须为 false,并且调用时整个音频已经加载完成;
  • AudioClip.SetData :部分支持,只能进行整体设置,忽略传递的 offsetSamples 参数。

SystemInfo.supportsAudio

WebGL 平台没有实现该参数,总是返回 true。

WWW.audioClip

只有浏览器原生支持的音频格式,才能够通过通过 WWW.audioClip 进行加载,详细的支持格式可以查询这里

如果只是选择音频格式,可以看下面的表格。

意图 推荐格式
通用的压缩格式 MP3
有损压缩 FLAC
未压缩 WAV

视频格式选择

意图 推荐格式
通用格式,开放格式 WebM
通用格式 MP4
高压缩比 3GP
旧设备兼容性好 QuickTime(mov)

Microphone

不支持