Three.js: Proposal: Bring Back Shadow Intensity (formerly Shadow Darkness)

Created on 27 Feb 2016  路  23Comments  路  Source: mrdoob/three.js

Shadows are greatly improved for MeshStandardMaterial and MeshPhongMaterial. However, shadows are very dark. It has been suggested that all one has to do is add AmbientLight to the scene to accommodate. Although that does brighten the shadowed areas, it also brightens everywhere else.

I propose a new property: THREE.LightShadow.intensity which takes values in [ 0, 1 ].

I prefer intensity to darkness, as IMHO it is less confusing. (What does shadow darkness of 1 mean?)

I see that Unity has shadow 'strength', which I believe is the same thing.

Here is a three.js hack to show it in action.

Note that shadows for MeshLambertMaterial are not currently correct, and they are not correct in this hack of three.js, either.

Suggestion

Most helpful comment

I ended up here because i have many meshes fading in and out at varying opacities that all cast shadows on lots of different meshes. Shadows are interpreted as either just on or off and pop in. This is not realistic. Something with 25% opacity should not have 100% shadow. Not sure how to handle this.

All 23 comments

I propose a new property: THREE.LightShadow.intensity which takes values in [ 0, 1 ].

+1

Note that shadows for MeshLambertMaterial are not currently correct

In fact, the current MeshLambertMaterial does not work properly at all.
Lucky for me, I use only Phong ...

I propose a new property: THREE.LightShadow.intensity which takes values in [ 0, 1 ].

:+1: I like the suggestion. It's inconvenient to brighten shadows with AmbientLight. I think an additional light property like intensity would provide more flexibility.

Note that shadows for MeshLambertMaterial are not currently correct,...

@WestLangley Can you tell us what problems with MeshLambertMaterial and shadows are existing?

I guess is just one more uniform per light. As long as the default is 1 I'm cool with it 馃槈

One could also view it as the opacity of the shadows.

I think an additional light property like intensity would provide more flexibility.

@Mugen87 All lights have an intensity property.

In fact, the current MeshLambertMaterial does not work properly at all.

@RemusMar That is a pretty strong statement. What specifically are your referring to?

@RemusMar That is a pretty strong statement. What specifically are your referring to?

https://github.com/mrdoob/three.js/issues/8161

@WestLangley Sry, i've meant LightShadow not Light....

Although that does brighten the shadowed areas, it also brightens everywhere else

can't you fix that with some gamma setting

However, shadows are very dark. It has been suggested that all one has to do is add AmbientLight to the scene to accommodate. Although that does brighten the shadowed areas, it also brightens everywhere else.

I propose a new property: THREE.LightShadow.intensity which takes values in [ 0, 1 ].

+1

Is there any update on this? I also find using ambient light hard to get everything right since it brightens up everything.

@mrdoob I think this thread is another +1 to per-material lights filter feature request

@makc you mean #5180?

just a general idea, I think if people could only have ambient light active on the surface with the shadow and keep the rest of scene unaffected, this issue could be solved.

OK, we can do something...

Here is the thing. For the physically-based materials ( Phong included ) shadows are treated properly as the absence of light. (This is why they are dark.) Making the shadows brighter in this case is a hack -- it is creating light that is applied only to areas of shadow.

You can see how hacky it is in the example I linked to above. If, in the console, you set

scene.children[ 3 ].material.roughness = 0; // the floor

you will see the hotspots stay bright as the shadow intensity is reduced.

A work-around is to add shadowIntensity to MeshLambertMaterial only. Shadows in that material are not treated as the _absence_ of light, but are simply a _darkening of the material's color_. So the required change is easy, and since MeshLambertMaterial does not have hot spots, it will work well.

Here is the change if you would like to experiment.

In src/renderers/shaders/ShaderLib/meshlambert_frag.glsl, replace

reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();

with

reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * ( 1.0  - ( 1.0 - getShadowMask() ) * shadowIntensity ); // to test, hardwire shadowIntensity

If adding shadowIntensity to MeshLambertMaterial (only) is acceptable, I will implement it.

@mrdoob Another workaround is to leave MeshLambertMaterial as is, and create another material similar to ShadowMaterial. (Maybe rename the current one ShadowOnlyMaterial).

Replace this:

gl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0  - getShadowMask() ) );

with this:

float p = ( 1.0  - ( 1.0 - getShadowMask() ) * shadowIntensity );

gl_FragColor = vec4( color * p, opacity );

/ping everybody : - )
@robhawkes
@serenayl
@MrMaksymov
@cedricr
@weiserhei
@casualbobuk
@titansoftime
@Mugen87
@makc
@bhouston
@sanschaise
@mrdumb

and create another material similar to ShadowMaterial

as you can see in #8659 people hate to create materials, they would rather bloat threejs with every little thing they need.

@WestLangley Maybe a dumb question: But why are shadows in MeshLambertMaterial not treated as the absence of light?

@Mugen87 idk, but maybe because light is done in vertex shader there

@WestLangley Maybe a dumb question: But why are shadows in MeshLambertMaterial not treated as the absence of light?

Because in MeshLambertMaterial, lighting is computed (per vertex only) in the vertex shader, while the shadow mask is computed in the fragment shader. In the fragment shader, the contribution and color of light from each light source is no longer separable.

I ended up here because i have many meshes fading in and out at varying opacities that all cast shadows on lots of different meshes. Shadows are interpreted as either just on or off and pop in. This is not realistic. Something with 25% opacity should not have 100% shadow. Not sure how to handle this.

I ended up here because i have many meshes fading in and out at varying opacities that all cast shadows on lots of different meshes. Shadows are interpreted as either just on or off and pop in.

Could you share a screenshot?

Here is the current scene, though i have encountered this other scenerios with fades too but was not sure how to address

screen shot 2018-05-03 at 9 14 11 pm

screen shot 2018-05-03 at 11 09 58 pm

I have buildings fading in and out when they are in the way as you rotate camera . The fade of the building is smooth but the shadows are on or off. would love to fade out the shadows with the opacity of the buildings that fade

Edit: Adding a vid here where i slow down the fade to exemplify the problem. You can see the shadow pop in when i turn the castShadow on or off at half opacity .

bldgs.mov.zip

Was this page helpful?
0 / 5 - 0 ratings

Related issues

filharvey picture filharvey  路  3Comments

konijn picture konijn  路  3Comments

yqrashawn picture yqrashawn  路  3Comments

boyravikumar picture boyravikumar  路  3Comments

Bandit picture Bandit  路  3Comments