GodotVR / godot_oculus_mobile

Godot Oculus mobile drivers (Oculus Go / Oculus Quest)
MIT License
170 stars 34 forks source link

Low Roughness results in black Specular Highlight #68

Closed NeoSpark314 closed 3 years ago

NeoSpark314 commented 4 years ago

When rendering a point light and a Spatial Material with low roughness values (for example 0.03) the resulting highlight becomes black instead of white. The left image shows a roughness value slightly bigger; the right shows the issue. artifacts_quest

In addition even when the highlight is not black as in the left there are disturbing flickering artifacts around the highlight.

On Desktop OpenGL everything renders as expected. So far I tested this only with SchlickGGX and GLES2; but Blinn seems to have similar problems with the flickering artifacts.

This issue was detected and mentioned originally by a user on discord. He shared the following Quest screenshot to show the problem: quest_reflect

My first guess for the cause of the issue is a floating point precision issue in the executed shader code that maybe leads to a division by zero. If this is the case I would assume that it can be reproduced also on other Android devices that have a fragment shader float mantissa precision of 10bit for mediump (thats the value for Quest) and is thus not specific to the Oculus Quest.

zlsa commented 4 years ago

I've encountered what I think is the same issue: https://youtu.be/T-JPEm10Tkg (screencapture from the Quest)

It occurs no matter what my roughness is set to, and gets worse as you get closer to the object. (Maybe something to do with fresnel?)

NeoSpark314 commented 4 years ago

Yes, this looks like the same issue. as described above. Thanks a lot for sharing the video. I will try to go through the shader code and see if it is sth. like a division by zero.

zlsa commented 4 years ago

If you'd like any specific demos with custom shaders or anything, I'm happy to test them!

zlsa commented 4 years ago

The black noise that appears when approaching the sphere appears only with panoramic or procedural skies. I made an EXR file that was white (1.0 brightness), and the sphere exhibits the noise; however, when using a sky color of white, the noise isn't present. Using a black EXR shows no noise.

Also, I'm using Godot 3.2 Beta 1.

NeoSpark314 commented 4 years ago

Do you have any other lightsource in the scene or only the sky? Are you using GLES3 or GLES2?

NeoSpark314 commented 4 years ago

I started looking closer into the problem with RenderDoc: it is definitely a again a shader precision problem:

Here is a capture of my test reproducer with a single point light: Screenshot from 2019-11-14 21-03-55

Defining in the shader the (#define USE_HIGHP_PRECISION which enables precision highp float; everywhere) produces on the quest the correct result:

Screenshot from 2019-11-14 21-04-15

I will try to find the location where it happens because I don't think at the moment that using float32 everywhere is a good solution (even though this is already the second instance of precision related bugs on the quest)

zlsa commented 4 years ago

GLES2, and I have the sky + a directional light (which doesn't change anything at all when I remove it.)

Also, with a 4096x2048 skybox, there are precision issues on the skybox as well (looks similar to nearest filtering.)

NeoSpark314 commented 4 years ago

Maybe activating full precision float globally is not as bad as I have thought. I did a basic benchmark by using a textured SpatialMaterial that covers the full view with a Sky and a directional light. You can see the traces in the screenshots below.

In summary the result was that with the current rendering the huge quad takes ~5.5ms per eye and with full precision enabled it takes ~6ms. It varies a bit with each run but this are roughly the worst case numbers I have seen in this test case. So it is less then a 10% increase in this scenario where every pixel is covered.

Screenshot from 2019-11-14 21-45-02

Screenshot from 2019-11-14 21-45-51

kaadmy commented 4 years ago

I can also reproduce this on a Motorola G4 using Godot 3.2-b1 using GLES2:

GLES2 float precision issues

NeoSpark314 commented 3 years ago

https://github.com/godotengine/godot/issues/44546 fixed it.