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

Logarithmic depth buffer gives no shadows #7815

Closed
hekto opened this issue Dec 18, 2015 · 27 comments
Closed

Logarithmic depth buffer gives no shadows #7815

hekto opened this issue Dec 18, 2015 · 27 comments

Comments

@hekto
Copy link

hekto commented Dec 18, 2015

https://github.com/mrdoob/three.js/blob/r73/examples/webgl_shadowmap.html#L136

change to

renderer = new THREE.WebGLRenderer( { antialias: true, logarithmicDepthBuffer: true } );

With that change, there are no longer any shadows.

Tested with r73 and dev as of today on Chrome Version 47.0.2526.80 (64-bit) and Firefox 43.0, both on Mac.

jsfiddle: http://jsfiddle.net/xrd3gcpy/

@mrdoob
Copy link
Owner

mrdoob commented Dec 18, 2015

Could you create a jsfiddle?

@hekto
Copy link
Author

hekto commented Dec 18, 2015

I added a jsfiddle with a moving directional light. When I run it i see a shadow when the light is furthest away, and the shadow disappears as the light moves closer to the objects, and then reappear again as the camera moves away.

The problem depends on the values of light.shadowCameraNear, light.shadowCameraFar in relation to the distance between the light and the objects.

@WestLangley
Copy link
Collaborator

Actually, Logarithmic depth buffer can be made to give shadows for certain parameter settings.
Another fiddle: http://jsfiddle.net/xrd3gcpy/1

@titoasty
Copy link

upvoting this one, it's still present and very annoying...

@sandromartis
Copy link
Contributor

Is there any update on this?

I don't manage to find any shadowCameraNear and shadowCameraFar values to get shadows to work with a logarithmic depth buffer.

I have a setup where I dynamically change the shadow camera box to fit it tightly around the scene extend to optimise shadows and it would be great if this would work together with logarithmic depth buffer.

@mrdoob
Copy link
Owner

mrdoob commented Aug 17, 2016

@jbaicoianu do you know if this is doable?

@fraguada
Copy link
Contributor

fraguada commented Sep 2, 2016

I have a similar situation to @sandromartis. Being able to use logarithmic depth buffer would be a great help as scenes being viewed can be in any number of incoming unit systems and scales. Here are a few simple jsfiddles of the same scene:
Logarithmic Depth Buffer = False
Logarithmic Depth Buffer = True

Does it have to do with the material shader chunks? I've tried MeshStandardMaterial, MeshPhongMaterial, and MeshLambertMaterial on the objects to no avail. Looking a bit deeper, I see that there are some ShadeChunks for logarithmic depth buffering, and it does seem that they are being included at least in MeshStandard(v)(f), MeshLambert(v)(f), and MeshPhong(v)(f):
logdepthbuf_fragment.glsl
logdepthbuf_pars_fragment.glsl
logdepthbuf_pars_vertex.glsl
logdepthbuf_vertex.glsl
I'm not too experienced with messing with shaders, so not sure that might be the issue, but this SO led me to investigate in there.

@WestLangley
Copy link
Collaborator

Changing the near and far plane of the shadow frustum can result in a shadow, but in this case, the shadow is not correct.

https://jsfiddle.net/3zjqdvkh/3/

@jbaicoianu
Copy link
Contributor

Hi, sorry I've been travelling and haven't had a chance to look at this. I'm not very familiar with the shadow map code but I believe either it would need to account for the altered gl_Position.z value when calculating the shadow, or the shadow map vertex shaderchunk would need to be moved before the logdepthbuf shaderchunk.

@fraguada
Copy link
Contributor

fraguada commented Sep 6, 2016

Hello. I made a quick test by naively changing the position of #include <logdepthbuf_vertex> to come after #include <shadowmap_vertex> so it looks like this:

    #include <shadowmap_vertex>

    #include <logdepthbuf_vertex>

In meshphong_vert.glsl, meshlambert_vert.glsl, and meshphysical_vert.glsl. These updates led to the same behavior and no forseeable difference. I do get the following in the console, but I'm not sure if it is related (Windows 10, Firefox Dev 50.0a2 (2016-09-01)):

THREE.WebGLProgram: gl.getProgramInfoLog() C:\fakepath(407,1): warning X4000: use of potentially uninitialized variable (_webgl_88e2b6533014e4f1_float4)

This is building master of r79 with the default build.bat (include common and extras). I say naively, because I don't usually touch the glsl files, so I'm not too sure of the consequences or benefits of changing the order of these #include statements.

@fraguada
Copy link
Contributor

Any other insight on this? Not sure where the problem lies or what would be necessary to attempt to fix this.

@jbaicoianu
Copy link
Contributor

I spoke with MrDoob about this yesterday actually. I really need the help of someone who understands how the shadowmap code works to fix this. The logarithmic depth buffer code only changes one value, gl_Position.z - but I don't understand how that is conflicting with what the shadowmap code is doing.

The original implementation for this was based on an article by Brano Kemen - I'll ping him on twitter and ask if he knows of any reasons why it would cause problems.

@jbaicoianu
Copy link
Contributor

jbaicoianu commented Oct 21, 2016

Dropping some URLs in here because all the information about how this particular logarithmic depth buffer implementation works is spread out over a series of blog posts. One of them apparently contains information about the shadow problem, and all are of interest to anyone who wants to know how it works and why/when they should use it

http://outerra.blogspot.com/2009/08/logarithmic-z-buffer.html
http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html
http://outerra.blogspot.com/2013/07/logarithmic-depth-buffer-optimizations.html

@Fyrestar
Copy link

Is this still a thing? Shadow for DirectionalLight with logarithmicDepthBuffer doesn't work.

@WestLangley
Copy link
Collaborator

@Fyrestar Yes, this is still a thing. logarithmicDepthBuffer does not properly support shadows.

@jbaicoianu
Copy link
Contributor

I wish I knew enough about shadows to fix this, but yes, as it is now shadows don't work properly with logarithmic depth buffer. I asked the original author of the technique who said that this topic was covered in the articles, but I couldn't find any reference, and I don't know enough about Three's shadow implementation to know how to solve it.

I would be more than happy to work with whoever might have the knowledge of the shadow code to figure out what needs changing to make this work.

@Fyrestar
Copy link

Fyrestar commented Sep 5, 2017

I found the issue. The depth shader uses logarithmicDepthBuffer, but the shadow coordinate input is worldPosition. This position is used for depth comparsion.

vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition

I removed the includes from the depth shader and the shadows working as usual.
logshad

@mrdoob
Copy link
Owner

mrdoob commented Sep 5, 2017

Oh!? Pull Request! 😮

@Fyrestar
Copy link

Fyrestar commented Sep 5, 2017

I guess the depth shader should get a kinda #ifdef USE_LDB since this might be a special usecase.

Another thing i noticed, but this is not related to this issue, is very pixelated edges for such meshes which cast an receive shadows. Wouldn't it help to remove the artifacts by using the camera-normal slope to early reject those faces in the depth shader for this purpose?

(this wall has a beveled edge)
shadedge

@WestLangley
Copy link
Collaborator

I found the issue. The depth shader uses logarithmicDepthBuffer, but the shadow coordinate input is worldPosition.

Well, yes. That is the issue.

But the solution you are proposing is to remove logarithmicDepthBuffer from the depth map calculation, instead of adding it to the shadow calculation.

That will work, but...

...it begs the question: Why are you using logarithmicDepthBuffer in the first place?

@Fyrestar
Copy link

Fyrestar commented Sep 5, 2017

Yes it basically could or should go the other way around, i only spotted what's the actual issue: worldPosition, which isn't touched for those calculations. But to use it for huge distances it also requires a shadow LOD / multiple lights for one source like a sun, as it gets super pixelated. If shadows are used for near distances only, it wouldn't matter.

Just to mention, maybe it's time to look into a more modern technique, it already has been mentioned the current implementation is way behind of those from modern ones (well we're a little restricted with WebGL). But even by using a small space and a whopping resolution of 2048x2048 (what isn't even supported by some devices) it looks super pixelated what is way too distracting.

I also just tried to post-render them, blur and reduce artifacts in screenspace. The result is much better but still has those edge pixel artifacts. I need to position the sunlight-camera to the world-camera, so motions also make them jump and flicker.
ssshad

@WestLangley
Copy link
Collaborator

Why are you using logarithmicDepthBuffer? Can you provide a simple, live example to demonstrate why it is needed in your case?

Your shadow frustum should be tight around your scene for quality shadows. Are your adapting the shadow frustum accordingly?

@Fyrestar
Copy link

Fyrestar commented Sep 6, 2017

The scene in the image is just for testing purposes, the actual world has real scale planets rendering thousands of kilometers and also close intersecting surfaces like water. Depth fighting was a big issue before, even for decent distances.

The shadow frustum is centered around the camera, basically it's a cube since it's a orthographic camera, i can decrease the distance, this increases the quality but shortens the distance. Using multiple shadows similar to geoclipping and fade them seems to be the only option for this case.

@WestLangley
Copy link
Collaborator

the actual world has real scale planets rendering thousands of kilometers and also close intersecting surfaces like water.

I expect your problems are self-imposed, then -- not three.js issues. There are limits to the precision of your machine.

The shadow frustum is centered around the camera, basically

For quality shadows, the shadow frustum should be tight around the rendered scene.

@Fyrestar
Copy link

Fyrestar commented Sep 6, 2017

This is the exact purpose of the logarithmic DepthBuffer, in fact the logarithmic DepthBuffer code is adapted from Outerra, you asked why it's needed in my case.

As i said, the frustum couldn't be any closer matching.

@WestLangley
Copy link
Collaborator

WestLangley commented Oct 14, 2017

I believe the following statements are correct as of three.js r.87:

For spot lights and directional lights:

Shadows work correctly with logarithmic depth buffer when the EXT_frag_depth extension is supported (a desktop workstation, for example).

Shadows do not work correctly with logarithmic depth buffer when the EXT_frag_depth extension is not supported, and logarithmic depth is implemented in software (for example, a mobile device).

For point lights, shadows work correctly in all cases.

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 19, 2019

see #17525 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants