mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
101.58k stars 35.29k forks source link

Light bleeding through #1153

Closed konijn closed 12 years ago

konijn commented 12 years ago

Greetings,

I have built a POC and placed it here : http://indie.demuyt.net/test1.html

There are 3 objects ( a floor, a block in the center and a little block ) and a spotlight pointing at the little block.

The floor and the block intersect, the spotlight is pointing at the little block, both are below the top of the center block and still you can see some light on the right hand side of the floor. Can anybody tell me why ?

Also, it seems as if the floor is more brightly lit when the litte sprite moves towards the corner of the floor, which doesnt make sense to me, but then again I am not an expert in webgl or any 3d.

You can move the little block ( sprite ) around by using the arrow keys.

T.

jeromeetienne commented 12 years ago

i hit the same issue

alteredq commented 12 years ago

See #1137:

https://github.com/mrdoob/three.js/issues/1137#issuecomment-3566628

konijn commented 12 years ago

Greetings alteredq,

I wrote http://indie.demuyt.net/test2.html which uses a pixel shaded Phong as a material and sets perPixel like mad. Still the light seems to just go through the center block.

Any idea what could cause this ? I am a total newbie, so there is a good chance it is a beginner error.

T.

alteredq commented 12 years ago

I'm not sure I understand, are you asking about shadows?

We don't have shadows for point lights.

You could try to hack something from SpotLights, which is like point light, just they cast shadow in single direction.

Proper shadows for point lights are rather expensive, they require to render scene 6x into cubemap (or maybe something like dual paraboloid maps for 2x extra scene render with quality trade-off).

konijn commented 12 years ago

Greetings,

I was indeed informed on IRC that point lights have no shadows, so my example uses a spotlight. ( variable pLight might be confusing, my apologies, but it is a spotlight ).

If you look at http://indie.demuyt.net/test2.html you will see that light reaches the right hand side of the floor. The centerpiece should have blocked that light.

How can I make sure that light gets blocked by the center block like real light would be ?

T.

mrdoob commented 12 years ago

The shadow parameters have now been moved from renderer to the light itself:

https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js

Follow the code of this example:

view-source:http://mrdoob.github.com/three.js/examples/webgl_interactive_draggablecubes.html

alteredq commented 12 years ago

Also, once you get shadows set up according to current examples, you can try to make shadow camera frustum visible to help you see what's going on:

https://github.com/mrdoob/three.js/blob/master/examples/webgl_shading_physical.html#L343 https://github.com/mrdoob/three.js/blob/master/examples/webgl_shadowmap.html#L116

Shadows are somehow pain to set up, this helps a lot.

jeromeetienne commented 12 years ago

When i look at dragable cube, i think i see the bug i hit. Faces which are hidden to the shaddow camera, are receiving the shadow. It is showing frequently when the object cast and receives shaddow.

alteredq commented 12 years ago

Shadow maps as a technique have plenty of artefacts. Unfortunately it's not something that "just works". I'm not even sure which problem you are referring to.

Objects outside of shadow frustum used to be dark but this issue I fixed. Only things in frustum should have a chance to be shadowed.

Faces getting shadows when they are lit (and when they are inside of shadow frustum) can be caused by self-shadowing. This can be countered by playing with shadowBias parameter.

Though draggable cubes example should be tuned not to have any strong artefacts (at worst there should be just slight darkening at the edges for some cubes).

If you used shadows before, please note that shadow behaviors changed a lot compared to r46. As usual, examples are good reference to see which parameter values produce decent results.

jeromeetienne commented 12 years ago

Maybe this is me misunderstanding it then. I did a test bed to be sure. It is currently live at http://learningthreejs.com/data/casting-shadows/ What do you think?

It seems like the shadows are casted on face which are hidden to the shadowcamera

First scene. a cylinder+cube + spotlight

Is that an expected artefacts ?

Second Scene

alteredq commented 12 years ago

first scene

This is not artefact, this is exactly what you asked it to be. Cylinder casts shadow and cube receives its shadow as expected (just it looks "out of place" as there is no shadow from cube to cube which in real world would make cube bottom fully shadowed).

second scene

This seems like self shadowing artefact. Cube's down side is correctly shadowed but also cube's up side is now incorrectly shadowed.

Additionally your shadow camera frustum doesn't fully enclose cube so some parts don't get shadowed.

Here you could try to expand light frustum and play with shadow bias.

jeromeetienne commented 12 years ago

so im a beginner at this. Just asking to be sure

it is normal that the faces hidden to the shadow camera will still receive shadow ?

if yes, is there a way to prevent this behavior ? i would like faces to receive shaddow only when they are facing the light projecting shadow.

alteredq commented 12 years ago

it is normal that the faces hidden to the shadow camera will still receive shadow ?

Yes, this is what shadows are, by definition.

if yes, is there a way to prevent this behavior ?

No, if you don't want to have such "standalone" shadows, the only thing you can do is try to get fully proper lighting and shadows.

Do not have any lights not casting shadows (this also means no ambient light), turn on shadow receiving everywhere and try to get proper self-shadowing so that object's light-facing faces shadow its light-opposite facing faces.

There is renderer.shadowMapCullFrontFaces flag (by default true) which you could turn off and have shadow maps use regularly rendered shadow casting objects (instead of default rendering using backfaces):

https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L59

With this though it's harder to avoid self-shadowing artefact on light-facing faces.

konijn commented 12 years ago

Greetings,

I am quite a bit out my depth here, but this sentence

and try to get proper self-shadowing so that object's light-facing faces shadow its light-opposite facing faces.

makes me think that I cannot get proper shadowing if the light moves around ?

Please see this dev movie ( http://www.youtube.com/watch?v=wsZLB9N3j4A ), at 1:50 you can see exactly what I am trying to attempt. A sprite with light and the light goes not beyond walls, I cannot seem to get there even following suggestions of spotlights and setting parameters on the light instead of the renderer and setting everything as receiveShadow and the center block as castShadow.

I will try the renderer.shadowMapCullFrontFaces flag though.

T.

PS : How does the shadowMapBias work ? What does it mean ?

jeromeetienne commented 12 years ago

@alteredq thanks for the info. now i got stuff to study ;)

(issue closed for me)

WestLangley commented 12 years ago

@konijn, here is a working fiddle: http://jsfiddle.net/87w27/ . Perhaps it will be of help to you.

alteredq commented 12 years ago

@konijn Aha, in that video they don't use shadows like we have.

This is isometric rendering, essentially it's 2d tiles made to look like 3d, and there are 2d shadows for omnidirectional point lights. Additionally even these are not full shadows, they are just per-tile, which makes it much cheaper.

Equivalent for us would be point light shadows, that we don't have, and also would be much more expensive in full 3d. So no, you can't achieve that effect easily.

You could try to have single spot light that would be shining light and casting shadow in one direction and then three spot lights that wouldn't shine light and cast shadow in 3 other directions.

But it seems you tried to jump into too complex thing, try first something simpler.

konijn commented 12 years ago

@WestLangley Thanks mate, that looks interesting. It is interesting that even after removing the ambient light, the shadow is not ink black, which is what I was expecting. My next approach is to simply hide objects on the other side of the wall.

@alteredq & co, thanks for helping me out. I think I know how I will proceed now.

T.

WestLangley commented 12 years ago

@konijn, the shadow is not ink black because light.shadowDarkness = 0.5.

konijn commented 12 years ago

@WestLangley Yes indeed, most interesting. I will play with this more.