three.js icon indicating copy to clipboard operation
three.js copied to clipboard

Add Shadows for Transparent Objects

Open gkjohnson opened this issue 5 years ago • 18 comments

A first pass at shadows for transparent objects as discussed in #10600.

I've modified an example here on another branch so you can see how the shadows are affected and the artifacts associated with this technique:

image

As I mentioned before the artifacts are pretty apparent but can be hidden a bit by setting the shadow radius to a good value. There may be some other shadow sampling techniques that can better hide the dither pattern.

gkjohnson avatar Mar 16 '19 03:03 gkjohnson

I just resolved the conflicts and made a few updates including using an 8x8 dither pattern as Babylon used. The example on another branch from the original post has been updated, as well, with a larger shadow map (2048 x 2048). Right now shadow transparency is universally toggled with renderer.shadow.dithering (like you mentioned in https://github.com/mrdoob/three.js/issues/10600#issuecomment-473140467) but it could be set per light -- perhaps that's a better place for it? It would be nice to move most / all shadowmap flags to the lights if possible I think.

And cc @donmccurdy -- you've mentioned an interest in introducing alpha hashing previously and this may be a start. The approach used here for shadows is just a 2d pattern seeded by screen space position so it's consistent but there could be other options in the future. For shadows, at least, using an alpha hash approach like you mention here might be noisier (even if it doesn't change per frame thought it might not be so noticeable) but would allow shadows of overlapping objects with the same alpha to to get darker:

image

gkjohnson avatar Nov 10 '20 23:11 gkjohnson

For alpha hash we'd probably want texture-space or object-space coordinates, but no matter here. I do see pretty noticeable banding though, viewed from an angle.

Screen Shot 2020-11-12 at 8 28 48 PM

... and I'm wondering if a small blue noise texture would do better? We can figure out how to embed it in the source code as a Uint8Array or Data URI if it gives good results.

donmccurdy avatar Nov 13 '20 04:11 donmccurdy

For alpha hash we'd probably want texture-space or object-space coordinates, but no matter here

Yeah I've taken a look at that presentation -- it is a slightly different technique but we could provide options to use various clipping approaches for transparency. Alpha hashing does look really noisy, though. Is it often used without some kind of temporal accumulation like TRAA?

Regarding the banding, though, I'm not sure if there's a great way to avoid a pattern here -- here's what the shadows would look like with blue noise (I've written a blue noise generator here):

https://raw.githack.com/gkjohnson/threejs-sandbox/bluenoise-shadows/screendoor-transparency/index.html

And here's the same demo with a 4x4 bayer pattern:

https://raw.githack.com/gkjohnson/threejs-sandbox/master/screendoor-transparency/index.html

I'm not sure if I feel it's a lot better.

gkjohnson avatar Nov 13 '20 06:11 gkjohnson

Alpha hashing does look really noisy, though. Is it often used without some kind of temporal accumulation like TRAA?

I don't think it needs to be (example: https://twitter.com/thespite/status/1221532206562258945), but, yeah there's certainly a grain. For alpha hashing (or even just starting with alpha dither, no per-object hash) I think I'd prefer a noise pattern to a screen grid. But for the shadows, agreed, the Bayer pattern appears to be working better. Tweaking the shadow radius seems to hide the banding, depending on the angle etc., that could work for now. 👍

donmccurdy avatar Nov 13 '20 07:11 donmccurdy

"mrdoob modified the milestones: r123, r124 23 minutes ago" :( Why ?

LinoPhil avatar Nov 25 '20 11:11 LinoPhil

@LinoPhil The milestone modification happens automatically when the assigned milestone is released and the PR is still open.

Mugen87 avatar Nov 25 '20 11:11 Mugen87

@Mugen87 ok, but the feature itself, you are not satisfied with the quality or is it breaking something? The demos look promising to me and im looking forward to use it in our viewer.

LinoPhil avatar Nov 25 '20 11:11 LinoPhil

@LinoPhil Sorry, there was just no opportunity to deeply review this PR so far. There are so many of them (with different priorities and complexities) and time is unfortunately limited.

Mugen87 avatar Nov 25 '20 12:11 Mugen87

Just want to give a push. Maybe after 3 years (initial ticket 10600) its time to finish?

LinoPhil avatar Mar 04 '21 10:03 LinoPhil

@gkjohnson I'd also be interested in this PR; seems only blocker was "review time" - happy to test drive this as well in case you find time to rebase it on latest dev.

hybridherbst avatar Nov 20 '22 16:11 hybridherbst

happy to test drive this as well in case you find time to rebase it on latest dev.

I appreciate it but unfortunately I've lost interest in this PR. I made it, rebased it, and resolved conflicts three times at the request of the project to review but have gotten no real feedback or direction on how to get it merged. If I'm asked to make changes or update a PR I think it's reasonable to read that as interest in the PR and for feedback to come. I understand there are a lot of PRs and issues that come through three.js but I'd just like to express that it is frustrating to be asked to do work and spend time on a problem with no follow up.

If someone is interested in picking this PR up and updating it to move it forward then by please do! I'm just preoccupied with other projects right now.

gkjohnson avatar Nov 21 '22 02:11 gkjohnson

Thanks! I fully understand the frustration 🙃

Maybe @donmccurdy can chime in if/how this PR relates to the recent draft of

  • #24271

hybridherbst avatar Nov 21 '22 09:11 hybridherbst

Maybe @donmccurdy can chime in if/how this PR relates to the recent draft of

  • https://github.com/mrdoob/three.js/pull/24271

My opinions here - I think alpha hashing is great but there is no one perfect solution for these things with transparency, shadows, anything. It's all hacks and the right solution depends on the desired result. Alpha hashing looks great when you can temporally resolve but otherwise it's extremely noisy as the camera or object moves.

Games like Mario Odyssey use a variety of patterns stylistically for different kinds of transparency including a comic-book-like dot matrix pattern for the main character. And most new high profile games like Assassins Creed Odyssey use a typical bayer pattern dither for transparency which is consistent in screen space and therefore less noticeable than a noisy hash jitter.

In terms of reducing shadow artifacts - it seems that Babylon.js has employed exponential variance shadow maps (EVSM reference) which seems to be useful when trying to blur out the artifacts.

Perhaps something like node materials will make this kind of subjectivity in handling material dither a simpler task 🤞

gkjohnson avatar Nov 29 '22 06:11 gkjohnson

Yeah, I think these are complementary. Perhaps we'd want to use the same dither patterns at some point but I am not too concerned about that now.

I'm not sure how useful Alpha Hashing will be for large, highly-visible transparent surfaces. As @gkjohnson mentions, the noise requires temporal resolution. However I do find myself wishing I could use Alpha Hashing when trying to do things like:

  1. subtly fade out an opaque object, without tons of alpha blending problems
  2. fading between two opaque objects (e.g. LODs)
  3. fading out the edges of an object (e.g. e.g. blades of grass fading into the ground)

These cases are less sensitive to noise grain.

donmccurdy avatar Nov 29 '22 15:11 donmccurdy

I don't think there's another good issue to post this in but it's relevant to the discussion here - Cesium (at least in Unreal) is using screenspace consistent dither patterns to fade between LoDs. Screen space consistency is particularly important here since the different swapping LoDs fade using inverted dither masks. So as the new model fades in a dither pattern - the old one fades out using the pixels that the new model is not rendering to yet.

https://cesium.com/blog/2022/10/20/smoother-lod-transitions-in-cesium-for-unreal/

gkjohnson avatar Dec 22 '22 01:12 gkjohnson

Looks like this feature has been added into react-three-fiber's Drei based on this PR. It was also added into Babylon (also based on my original sandbox example 😅) and Playcanvas, as well.

gkjohnson avatar Dec 24 '23 04:12 gkjohnson

Yes, we should rebase and merge the PR!

Mugen87 avatar Jan 06 '24 16:01 Mugen87

we have same issue when rendering hair(transparent texturing) shadow, looking forward to get this feature in next release, thanks for the good work.

iefreer avatar Jan 15 '24 09:01 iefreer