问题
I have posted the same question over Unity's forum, but there hasn't been any answer and thus posting it here, too.
I have been trying to run a Unity WebGL build in headless mode (through puppeteer) while saving 'screenshots' of the game, but the camera rendering doesn't seem to be working. The resulting images are all black.
It works as expected when not in headless mode (but still WebGL). It also works properly in standalone builds (e.g., windows, mac), through -batchMode.
Here's the code in question:
// Problem seems to be in the following 2 lines
RenderTexture.active = camera.targetTexture;
camera.Render();
// same dimensions, both in headless and not headless
Debug.Log("CAMERA TARGET TEXTURE WIDTH: " + camera.targetTexture.width);
Debug.Log("CAMERA TARGET TEXTURE HEIGHT: " + camera.targetTexture.height);
tempTexture2D = new Texture2D(camera.targetTexture.width, camera.targetTexture.height, TextureFormat.RGB24, false);
tempTexture2D.ReadPixels(new Rect(0, 0, camera.targetTexture.width, camera.targetTexture.height), 0, 0);
tempTexture2D.Apply();
// RGBA(0.000, 0.000, 0.000, 1.000): totally black, when in WebGL headless mode. Works fine otherwise.
Debug.Log(tempTexture2D.GetPixels(100, 100, 1, 1)[0].ToString());
// Encode texture into JPG
byte[] bytes = tempTexture2D.EncodeToJPG();
// byte count is almost half when in headless mode
Debug.Log("IMG " + frameNumber + " byte count: " + bytes.Length);
// save to persistentData (indexedDB in WebGL)
// that data is then read on client side and encoded again
I found some differences between the Webgl headfull and headless versions (respective pictures below).
I have also tried to set --use-gl=swiftshader
which has better gpu stats, but still shows everything in black:
To be clear, the arguments I'm passing to chromium are the following:
args:[
'--headless',
'--hide-scrollbars',
'--mute-audio',
'--no-sandbox',
'--use-gl=swiftshader' // tested with and without
]
The headless log output coming from unity is the following:
PAGE LOG: Loading player data from data.unity3d
PAGE LOG: Initialize engine version: 2018.4.10f1 (a0470569e97b)
PAGE LOG: Creating WebGL 2.0 context.
PAGE LOG: Renderer: WebKit WebGL
PAGE LOG: Vendor: WebKit
PAGE LOG: Version: OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium))
PAGE LOG: GLES: 3
PAGE LOG: EXT_color_buffer_float GL_EXT_color_buffer_float EXT_float_blend GL_EXT_float_blend EXT_texture_filter_anisotropic GL_EXT_texture_filter_anisotropic OES_texture_float_linear GL_OES_texture_float_linear WEBGL_compressed_texture_etc GL_WEBGL_compressed_texture_etc WEBGL_compressed_texture_etc1 GL_WEBGL_compressed_texture_etc1 WEBGL_compressed_texture_s3tc GL_WEBGL_compressed_texture_s3tc WEBGL_debug_renderer_info GL_WEBGL_debug_renderer_info WEBGL_debug_shaders GL_WEBGL_debug_shaders WEBGL_lose_context GL_WEBGL_lose_context
PAGE LOG: OPENGL LOG: Creating OpenGL ES 3.0 graphics device ; Context level <OpenGL ES 3.0> ; Context handle 1
PAGE LOG: UnloadTime: 0.340000 ms
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_OPERATION : glFramebufferTexture2D: <- error from previous GL command
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_OPERATION : GetShaderiv: <- error from previous GL command
PAGE LOG: WebGL: INVALID_OPERATION: renderbufferStorageMultisample: samples out of range
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glClear: framebuffer incomplete
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glDrawElements: framebuffer incomplete
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glDrawArrays: framebuffer incomplete
PAGE LOG: [.WebGL-0x7fcdb69e1600]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glBlitFramebufferCHROMIUM: framebuffer incomplete
Could the problem be the WebGL hardware acceleration altogether? Can I disable it from my WebGL build?
This issue seems to be related with: Rendering WebGL image in headless chrome without a GPU
But that seems to be working properly, at least under MacOS: https://github.com/Apidcloud/WebGLHeadlessRendering
So I'm still assuming it has something to do with Unity3D. Even if headfull, it will become black when using swift shader
, with the only gpu stats difference being video decode--hardware acceleration disabled:
Thanks!
Edit with answer (more details on the actual answer below):
It finally works by disabling the anti-aliasing in unity, which seems to throw some OpenGL errors. Works with and without swift shader
.
回答1:
After 2 or 3 days struggling with this and trying to find the exact problem, it finally works by disabling the anti-aliasing in unity, which seems to throw some OpenGL errors.
That said, the Unity3D WebGL rendering works headlessly (through chromium and puppeteer) even without swift shader
, though that is probably what you want for no-gpu
scenarios (e.g., some server).
The log output, though still weird, for both scenarios (with and without swift shader
) is the following (note that the framebuffer incomplete errors are gone):
PAGE LOG: [.WebGL-0x7f842a0f6400]GL ERROR :GL_INVALID_OPERATION : glFramebufferTexture2D: <- error from previous GL command
PAGE LOG: [.WebGL-0x7f842a0f6400]GL ERROR :GL_INVALID_OPERATION : GetShaderiv: <- error from previous GL command
Thanks!
来源:https://stackoverflow.com/questions/61239552/unity3d-webgl-headless-not-rendering