Open goatchurchprime opened 2 years ago
The OpenGL backface check isn't available in GLES2, so the only workaround is to duplicate your thin wall to make it visible on both sides.
The OpenGL backface check isn't available in GLES2, so the only workaround is to duplicate your thin wall to make it visible on both sides.
Is the "backface check" you are referring to gl_FrontFacing
? (or the FRONT_FACING
built-in shader variable? )
Because it is exposed in Godot's GLES2 and works fine.
(It's fragment-shader only, which makes sense since faces can't be represented in a vertex shader!)
I just tested putting if (!FRONT_FACING) { NORMAL *= -1.0; }
anywhere in a custom shader's fragment function and it fixes the issue, so I'm fairly certain plopping that into GLES2's scene.glsl
would do the trick?
(Maybe GLES2 is lacking in features but like come on, gl_FrontFacing
seems to be from OpenGL 1.00! x)
That does work for my case, because I happen to have the spot-light positioned close to the camera, so this inverted normal is aligned correctly for it. I don't know how general this solution is (if this is good enough for lights in other places).
The FRONT_FACING feature is probably so you can apply a different base texture/colour depending on which side of the surface you are seeing.
I don't know the right answer, (hacking the light() function vs hacking the normal orientation), but whatever it is it should be as same as possible between GLES2 and GLES3.
Godot version
3.3.3.stable
System information
GLES2, Linux and Android Quest2 VR
Issue description
I have zero thickness walls (with "cull_disabled" to see both sides) with a SpotLight near the Camera.
This does properly show the "albedo_texture" on the back-faces, and gives a washed out appearance (as if only the ambient light is active).
Lower square in left image is when the MeshInstance faces towards the camera (and the light), Lower square in right image is when the MeshInstance faces away from the camera (and the light),
The upper square is the result of playing with the shader code, by inverting the NORMAL vector, like so:
The result is that the square is bright on its back-face and dark on the front-face.
There is a
light()
function that can be used in the shader code, although it is not given to you by the "Convert to ShaderMaterial" option, and there are few clues about what its default code is.I think when the
light()
function is not defined it is controlled byrender_mode
values such asdiffuse_burley
,specular_schlick_ggx
.It is not known whether a custom
light()
function would always lack the performance of these preset render_modes.The one example of a custom light function given in the docs is:
Clearly this will give 0.0 whenever the NORMAL and the LIGHT point in opposite directions.
One way to fix this is to wrap an
abs()
around thedot()
function so that the dot product is always positive.The GLES3 renderer doesn't have this problem, but it does not appear that it is fixed with an
abs()
function. Instead, it looks like it inverts the NORMAL of a mesh when the backface is facing to the camera, since my inverted normal vertex shader (used on the top square) shows up dark on both sides.It is hard to know where to look for these technical rendering details so I can work with them instead of against them.
I am using GLES2 because I am developing for the Quest2 VR, which isn't powerful enough to run GLES3
Steps to reproduce
Example below has an animation player to spin the mesh instance squares in view of the light and the camera
Minimal reproduction project
gles2lightbug.zip