-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
Should lightMap/aoMap occlude lights? #7377
Comments
Specular reflection is a method in most shaders that employ the Phong shader model to make it seem like the light is bouncing off the material directly into the camera to make certain parts brighter instead of just diffuse shading. Shadows is created by something blocking the light from ever reaching anything behind the object in question. If the shadow is supposed to block light, then why is it not blocking specular lighting? This defies the very reason to implement shadow maps in the first place. In my opinion this possible bug looks terrible. I looked at the shader model in Three.js and shaders are created specifically for each material and their sub-properties. I always thought that this specuar/shadow ordeal is just a bug in how these shader blocks are concatenated like they are put in the wrong order. Change it? Yes. This would apply to the Ambient Occlusion Map and the regular texture of the object. Blocked light should simply be treated like no light. Just my two cents. |
A Currently, there are three sources of ambient (or indirect) diffuse light in three.js: An So the Aside: Indirect light can reflect diffusely or specularly. I have only mentioned indirect diffuse light. The other is indirect specular light. three.js does not have any models currently for indirect specular light. |
The shadow mapping code in three.js is a hack. It only darkens the reflected light. The hotspot is so bright, that even when darkened, it still has a value greater than 1, so it appears white. The shadow mapping methodology in three.js will hopefully be changed to properly block incoming light sources. There have been multiple discussions on this board about that topic.
No. See my post above. |
@WestLangley I misunderstood how the ambient occlusion map. I know what ambient occlusion is as I read countless articles and implemented such a thing when playing around in OpenGL in c++ using ray marching (kind of). I just have never herd of ambient maps but I guess such a technique is needed because WebGL is so limiting. If the shadow mapping is a 'hack' that simply darkens the region in shadow why not go the whole nine yards and darken it to 0 and use a regular ambient light or the lightMap to lighten it back up a little bit? I did this when creating shaders that process shadows and it looks fine. |
Is that not what the library does now if |
I'm just speaking out of ignorance of the library now: why would such a feature to control shadow darkness be implemented then if it causes the issues that @mrdoob proposed but can be done differently while not having such issues? This would just bloat the shader and javascript needing to manage an extra uniform or however you send lighting data to the shader. |
I think talking about shadowmaps is not relevant here. I'm arguing that, either Technically this is simple, just multiply the specular with the pixel value of the greyscale map. So... seems like, either we are mistaken on how |
I mean, is there a way we can produce the desired effect right now? |
Hmm... Wait I guess the solution is to use the same texture as D'oh... |
In particular, |
Having said that... I think something is still wrong... aoMap: totalAmbientLight *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; I think this one is fine. However... lightMap: totalAmbientLight += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; As far as I understand (http://wiki.polycount.com/wiki/Light_map), I think this would be more useful? diffuseColor.rgb *= texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; That way, |
Hmm... I'm experimenting and it's difficult. If anything, if totalDiffuseLight += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; |
See the detailed discussion and history in #6263 I happen to agree with @bhouston on this one as far as the decision to treat light maps as a source of light. To treat them as multiplicative, as we currently do shadows, is an option, but it will not be consistent with our decision to move to more PBR-based approaches. |
This is a reasonable debate to have. Some uses may use light maps to bake direct light-sources, so in that sense they can represent both indirect and direct light. Whatever we do, users who think of light maps as multiplicative will have a problem with our approach. /ping @bhouston |
@bhouston explains our current implementation of light maps well:
|
Hi guys! Lightmaps represent the full additive contribution of a baked light. If you have other lights in the scene, they may be able to light an area that is in shadow of a baked light -- that is okay, because it is a different light, only the baked light is for sure occluded in that spot, not the dynamic light (it may or may not be occluded at that spot, it is based on the dynamics light position.) Dynamic lights need to use shadow maps in order to case shadows. The main thing in the first example is that the dynamic light should be using its own shadow map to have it occluded by the object. I think one of the confusing issues is that our shadow maps often are not actually occluding lights completely, they just slightly darken them (or at least they did last time I checked), which is really not that affective at all on a specular highlight. |
That makes sense. So, then it would be logical that |
You are correct, our lightMap only contains the diffuseLight component, not the specularLight (which is directional) or ambientLight. There are more advanced lightMap implementations that contain directional components, but they are not well supported by baking tools (I do not think any generic baking tools support them.) |
No. |
The components of light we model are indirect diffuse, indirect specular, direct diffuse, and direct specular. I will modify the code to use those terms so we do not have this confusion. |
Can we use the term direct and indirect rather than direct and ambient? I got confused because I thought that ambient has multiple meanings. |
Agreed.
I know this is confusing. I will fix the code to use consistent terms. |
@WestLangley BTW if you wanted to contribute to this PR it basically works and uses this terminology: #7324 I was thinking that maybe we should add these structs anyhow, even if they are incompatible with @unconed's shader graph stuff. |
Say that we want bake the illumination in a scene (so we have nice shadows) and then we put dynamic lights in the same position so we can produce specular lights. Would one need to do a custom shader for this? |
I've seen an option on lights to "affect diffuse" or "affect specular" -- thus it is a light option. |
This light option can be put on all lights that offer specular. |
Yeah, I was studying structs now. Was aiming to clean/implement this week. |
I can spend a bit of time tomorrow to clean it up a bit. It does work in its current state, just some of the examples are broken. |
But that's the thing, neither Using |
That'd be great! 😊 |
They do not by design though. I'd argue that the use of the specularMap in the first example to occlude the specular only appears to work but it really blocks too much -- it will screw up specular from lights that are not behind the car, which shouldn't happen. The specularMap basically says that the surface is very rough and doesn't not reflect specular light, no matter where it comes from. My understanding is that dynamics lights really should use their shadow maps to reduce their contributions. And you could have them be only specular if you need them to be so that you can combine then with baked shadows (but that will only really work if the lights still have shadow maps to avoid specular shining through objects.) What we should do is have all shadow maps calculated first and their indices stored with the light structs that are passed to the renderer. Then as one is calculating each light contribution you check its shadow map to see if it is occluded, and that determines if you accumulate the lighting result or not. This is significantly more accurate and realistic than the darkening post-accumulation effect we currently do. |
Sounds good! I'll experiment a bit. |
I was messing with this example the other day, and I noticed that the shadow gets affected by the specular.
At the moment, the example is using this texture as color map. I tried creating a plane in editor and applying the texture both as
lightMap
andaoMap
and the specular goes through it.This other example has the same issue.
I'm confused about the difference between
lightMap
andaoMap
, but I bet one of them should be able to occlude specular lights 😇Related: #6573
/cc @WestLangley
The text was updated successfully, but these errors were encountered: