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

Add shadow map support for RectAreaLights (brainstorming, R&D) #14161

Open
bhouston opened this issue May 28, 2018 · 62 comments
Open

Add shadow map support for RectAreaLights (brainstorming, R&D) #14161

bhouston opened this issue May 28, 2018 · 62 comments
Milestone

Comments

@bhouston
Copy link
Contributor

Description of the problem

It would be very useful for realism to support shadows on RectAreaLights.

I am unsure of the best technique to use here as I have not researched it yet beyond some quick Google searches. I am not yet sure what is the accepted best practice in the industry?

Two simple techniques I can think of:

  • one could place a PointLightShadowMap at the center of a rect area light and it would sort of work.
  • less accurate, one could place a SpotLightShadowMap with a fairly high FOV (upwards of 120 deg, but less than 180 deg as that would cause it to fail) at the center of the rect area light and point it in the light direction.

(I believe with the spot light shadow map you may be able to get better results for large area lights if you moved the shadow map behind the area light surface so that the front near clip plane in the shadow map frustum was roughly the side of the area light as it passed through the area light plane. I believe I read this in some paper once, but I can remember the source of it.)

@bhouston
Copy link
Contributor Author

/ping @abelnation if you have any ideas as you are the current resident Area Light expert. :)

@WestLangley
Copy link
Collaborator

WestLangley commented May 28, 2018

I refactored the area light code and I am familiar with it, too. For shadow support, see https://eheitzresearch.wordpress.com/705-2/.

@bhouston
Copy link
Contributor Author

For shadow support, see https://eheitzresearch.wordpress.com/705-2/.

Interesting. I think that may be a bit too computational intensive for WebGL at this time though as it makes an assumption that ray tracing is hard ware accelerated. It is likely years before that comes to WebGL unfortunately.

@bhouston
Copy link
Contributor Author

I've of the opinion that while my two suggestion (point or spot light shadows) are not physically accurate when it comes to soft shadows, they are better than no shadow and are both very fast (as fast as our other shadows at least) and easy to implement (as the code already exists.)

@WestLangley
Copy link
Collaborator

@bhouston Oh, yeah... there is also #13057.

If you read the entire discussion, I think the consensus was to add 'cookie' support to SpotLight, which would presumably allow for a rectangular shadow.

@gkjohnson
Copy link
Collaborator

NVidia's Percentage Closer Soft Shadows do a decent job of approximating area light shadows. I was toying with hacking them in to a THREE.js scene here: https://gkjohnson.github.io/threejs-sandbox/pcss/index.html. It's using a directional light shadow map, at the moment, but a spotLight one might be better.

They're not perfect solution, though -- they have some artifacts when shadow edges get closer to each other and require a lot of samples to get a really smooth shadow.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 22, 2018

Looks great! But your demo runs with just 6 FPS on my iMac ^^

@looeee
Copy link
Collaborator

looeee commented Jul 22, 2018

I'm getting 60fps on a GTX 970m.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 22, 2018

1 FPS on my Pixel 😢

@bhouston
Copy link
Contributor Author

bhouston commented Jul 22, 2018 via email

@Mugen87
Copy link
Collaborator

Mugen87 commented Jul 22, 2018

There is already a pcss implementation in three.js that myself and oreshant wrote a while back.

https://threejs.org/examples/#webgl_shadowmap_pcss

This runs with nice 60 FPS on my iMac^^.

@gkjohnson
Copy link
Collaborator

There is already a pcss implementation in three.js that myself and oreshant wrote a while back.

I hadn't seen that! It looks good. I didn't know you could generate poisson disk-like values that way -- it looks like it has a nicer distribution and gives better results than the way I was using. I may borrow that if you don't mind!

1 FPS on my Pixel 😢

Ha! It wasn't working on my phone, either. I didn't optimize it at all and there's a lot of work going on in loops that could be moved out.

@bhouston's implementation is pretty fast, though. Maybe there's some variant of this that can be used for area light shadows? It would be nice to have any kind of shadow support for area lights so this type of implementation could be more easily plugged in.

@mrdoob mrdoob added this to the rXX milestone Jul 26, 2018
@sam-g-steel
Copy link
Contributor

NVidia's Percentage Closer Soft Shadows do a decent job of approximating area light shadows. I was toying with hacking them in to a THREE.js scene here: https://gkjohnson.github.io/threejs-sandbox/pcss/index.html. It's using a directional light shadow map, at the moment, but a spotLight one might be better.

They're not perfect solution, though -- they have some artifacts when shadow edges get closer to each other and require a lot of samples to get a really smooth shadow.

Nice! It's not perfect but it looks better than no shadow... I get 30fps on my Asus ROG Phone 2.
And 45fps on my integrated graphics laptop.

@sam-g-steel
Copy link
Contributor

sam-g-steel commented Dec 17, 2019

Here is an example of raytraced shadows in three.js only the shadow component is being shown in these videos.

60+fps with 1 shadow sample per pixel... With some smart filtering the results could look pretty good.

https://youtu.be/O21mKUtMtSg
https://youtu.be/2Tn93hf9kNw

This could be used to help with rect area light shadows.

A live web demo is in the works.

Related
#13908 Improving Shadows
#14048 Soft Shadows via Light Source Sampling
#14051 Adopting a Progressive Photorealistic Global Illumination in Three.JS

@mrdoob
Copy link
Owner

mrdoob commented Dec 17, 2019

Very nice!

@mrdoob
Copy link
Owner

mrdoob commented Dec 17, 2019

Related issue: I don't know how to implement some sort of shadows with the current IBL code.

Say that I want to add a DirectLight in the car example but ignore the actual light source and only use the shadow map to affect the IBL code.

@sam-g-steel
Copy link
Contributor

I've been playing around with several ray traced effects.

  • Shadows - from direct light sources, including rect lights
  • Ambient Oclusion
  • Global Illumination

Of the 3 I think per-pixel GI which would work with IBL is the hardest to achieve real time frame rates.

However, per-vertex GI and might be possible at good frame rates. The ray tracing code is being written with the idea that vertex and fragment shaders will be able to use it.

@sam-g-steel
Copy link
Contributor

@mrdoob, @WestLangley,
What space are the uniforms "pointLights[].position" in???
I'm doing the ray-tracing in world space but the shadows don't seem to match up.

Annotation 2019-12-20 073556

@sam-g-steel
Copy link
Contributor

Ok, after looking into it... It looks like it is in model view space... Is there a good way to get the light positions in world space?

Modify WebGLRender to send in both world and view space?

@sam-g-steel
Copy link
Contributor

Ok, I got it working with a point light... now to test rect area lights!

image

@bhouston
Copy link
Contributor Author

bhouston commented Dec 23, 2019 via email

@bhouston
Copy link
Contributor Author

bhouston commented Dec 23, 2019 via email

@sam-g-steel
Copy link
Contributor

@bhouston I think #14048 is what you are talking about.

I liked the demo with the twisted knot lighting source . I guess the problem that I saw is that the reflection of the light source never resolved to the correct image.

One plus for the ray-traced shadows is that It be used to handle transparent shadows. It can also be used for Global Illumination and many other lighting effects.

@bhouston
Copy link
Contributor Author

bhouston commented Dec 23, 2019 via email

@sam-g-steel
Copy link
Contributor

@bhouston I like solution proposed in #14048... especially for simple geometries like a rect light.
It looks like that method should be pretty easy to employ. Is there a fork of three that has this solution?

Regarding the ray tracing... On desktop class hardware the ray tracing solution works in real-time at 1spp. See... https://youtu.be/amX3icmbpzY.

I have not yet tested mobile.

In the demos that I've been working on, the lighting term is calculated using existing code but the shadow is ray traced instead of shadow mapping.

@sam-g-steel
Copy link
Contributor

sam-g-steel commented Jan 4, 2020

@mrdoob, @bhouston
So, I updated the demo to reflect Nvidia's rtx demo from GDC 2018

And I have it running real-time on my laptop and on my cellphone...

Laptop demo... https://youtu.be/MKCKXRVks3I
Cellphone demo... https://youtu.be/P-cnT2hYNF4

I also improved the distribution of the shadow samples to improve shadow realism

@sam-g-steel
Copy link
Contributor

sam-g-steel commented Jan 14, 2020

@mrdoob, @WestLangley , @bhouston and others

I got shadows for rect area lights working with raytracing.

Screenshot_20200113-175554647
The demo shown here... https://youtu.be/tZmlb29OUBU
Has point lights and a rect area light.

Some improvements to the distribution of shadow samples are in the works. Also, it looks like for area lights 2 shadows will need to be calculated for each light. A diffuse shadow and a specular shadow.

At present only the diffuse shadow is being calculated.

I plan on setting up a live website with this demo and also pushing these changes to my fork of three soon

@mrdoob
Copy link
Owner

mrdoob commented Jan 14, 2020

That's looking great! Does it only use a single depth texture too?

@sam-g-steel
Copy link
Contributor

Still working on the ray-tracing fork... I hope to have more to show in a few weeks.
I've been working on noise filtering to improve frame-rates and image quality.

@sam-g-steel
Copy link
Contributor

sam-g-steel commented Mar 18, 2020

Below are some pics of the noise filter...
It's still a work in progress.

Update 3/28/2020
3-28-2020

@mrdoob
Copy link
Owner

mrdoob commented Jul 2, 2020

https://ciechanow.ski/lights-and-shadows/

@atul-mourya
Copy link
Contributor

atul-mourya commented Jun 5, 2021

Eagerly waiting for this feature ( nearly 3 years since its proposal ). Wondering if there's any PR raised for it.

@mrdoob
Copy link
Owner

mrdoob commented Jun 24, 2021

@bhouston
Copy link
Contributor Author

bhouston commented Jun 24, 2021 via email

@mrdoob
Copy link
Owner

mrdoob commented Jun 24, 2021

Oh...

@N8python
Copy link
Contributor

N8python commented Jun 4, 2022

Currently testing some shadowing techniques for rectangle lights.
Screen Shot 2022-06-04 at 7 15 58 PM
Not sure if anything will come of it. Lots of work to be done.

@N8python
Copy link
Contributor

N8python commented Jun 6, 2022

Alright - I've been working on this problem a lot more and I've made some progress. I decided to go with @bhouston's solution of a spot-light with a high fov (150 in this demo) and a near plane aligned with the rectarealight. Results are promising.

mmmshadows_DxPmLdyt.4.mp4
rotate.mov

(100 FPS on an M1 Macbook Pro)

Caveats:

ATM I'm fitting the near plane to the light manually. If anyone has big math brain, how to do this automatically?

Very hacky PCSS implementation (also kinda slow). Final thing should probably use a more efficient algo - maybe VSM?

Lighting is also currently done is post-processing pass (for ease of testing). A simple nDotL model is used - not accounting for the area of the RectArea light. For the final thing the shadowing should be integrated with the default THREE.JS lighting setup.

@mrdoob
Copy link
Owner

mrdoob commented Jun 7, 2022

Hmm... The shadows look strange to me... 🤔
Have you compared it with how Blender would render that scene?

@mrdoob
Copy link
Owner

mrdoob commented Jun 7, 2022

A simple nDotL model is used - not accounting for the area of the RectArea light.

Oh, I see...

@N8python
Copy link
Contributor

N8python commented Jun 7, 2022

A simple nDotL model is used - not accounting for the area of the RectArea light.

Oh, I see...

Don't worry - I'll fix this later when integrating with built-in shadow system.

@N8python
Copy link
Contributor

N8python commented Jun 7, 2022

@mrdoob - Here is an example with an actual RectAreaLight. Does it look more accurate?

real.mov

@mrdoob
Copy link
Owner

mrdoob commented Jun 8, 2022

Hmm... I think these shadows are supposed to be way softer...

Screen.Recording.2022-06-08.at.11.52.25.AM.mov

@N8python
Copy link
Contributor

N8python commented Jun 8, 2022

Yea - thats definitely a limitation of the spot-light-esqueness of the technique. I'm just basically doing spot light shadow map + some near plane modification + high fov + pcss. The issue with uber-soft shadows like that is that not only are they really performance intensive to generate they also break often due to the way pcss finds blockers. The radius is simply too large. Then again this could be cuz i am dum and implemented the algo wrong.

Screen Shot 2022-06-07 at 11 17 05 PM

(Example of artifacts - credit @gkjohnson )

Upon further examination - I don't think there is much hope for progress down this avenue - the reason being is that gkjohnson's pcss example from all the way back https://gkjohnson.github.io/threejs-sandbox/pcss/index.html still does a great job of approximating area light shadows - the best I think we can get with this technique.

Another thought I had was the use of dual paraboloid mapping - just one paraboloid for the rectarealight. It would certainly be efficient and do a better job than a high-fov frustum. I'm just not sure of how well it'd integrate into the current three.js core.

@N8python
Copy link
Contributor

I've made a bit of progress over the fast few months - current working demo is here https://n8python.github.io/rectLightShadow/

This shadows properly obey the shape of RectAreaLights (try rotating the emitter for a funky shadow dance), though they are a bit slow and might not be entirely physically accurate (idk i am smol brain).
Screen Shot 2022-09-20 at 4 42 36 PM

@N8python
Copy link
Contributor

N8python commented Sep 20, 2022

It does a decent job against actually physically accurate results:
Blender:
Screen Shot 2022-09-20 at 5 45 04 PM

Mine:
Screen Shot 2022-09-20 at 5 47 26 PM

The only issue is that the blender render was much softer than mine - I had to make the light 5x bigger on both axes to get comparable softness. Here's a light of the same size as the blender render - I think the disparity is because I'm using raymarching, not raytracing.
Screen Shot 2022-09-20 at 5 54 43 PM

@marcofugaro
Copy link
Contributor

@N8python good job!! runs at 60fps on my laptop

@N8python
Copy link
Contributor

@marcofugaro TYSM! You must have one powerful laptop ;)

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 21, 2022

On my eight(!) year old 5k iMac the demo still runs at 30 FPS which is quite remarkable considering the complexity of the effect. 👍

@LeviPesin
Copy link
Contributor

LeviPesin commented Sep 21, 2022

Runs at 4 FPS (with denoise) and 6-7 FPS (without) on my five-year-old laptop ;-)

@N8python
Copy link
Contributor

On my eight(!) year old 5k iMac the demo still runs at 30 FPS which is quite remarkable considering the complexity of the effect. 👍

WOAH! That's kinda crazy. And I didn't even optimize it - there's still a plethora of unnessacary texture fetches to work on.

@N8python
Copy link
Contributor

Runs at 4 FPS on my five-year-old laptop ;-)

Can't win em all 😢

@atul-mourya
Copy link
Contributor

atul-mourya commented Sep 21, 2022

30 FPS on 2019 13'' Macbook Pro without denoise. With denoise, 42 FPS. Loving it 🥇

@LeviPesin
Copy link
Contributor

Can't win em all 😢

That's just a AMD video card from 2014 :-) (AMD A8-7410 APU with AMD Radeon R5 Graphics)

@N8python
Copy link
Contributor

30 FPS on 2019 13'' Macbook Pro without denoise. With denoise, 42 FPS. Loving it 🥇

Awesome! I get 60-90 FPS w/ denoise on a 2021 M1 Mac.

@N8python
Copy link
Contributor

Works with skinned meshes too!

Screen Shot 2022-09-22 at 7 38 56 PM

Repository owner deleted a comment from Codezigineer Apr 21, 2024
@Codezigineer
Copy link

Codezigineer commented May 12, 2024

It’s possible to use directional light shadows with a very long and wide frustum to simulate RectAreaLight shadows without expensive PCSS. See here. It uses a directional light shadow map.

Note that the max size of the frustum before objects no longer have light is the dims of
the light * intensity of the light * 255.

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