I’m working on a website that lets the user upload artwork and place it in a gallery. The gallery is a baked scene, however the artwork is created during run-time. I’m not sure what the best course of action would be to better blend in the dynamic content to the baked scene.
The scene consists of multiple rooms so I’m not sure light probe, as it currently stands, would work (one light probe for the entire scene I believe) as the lighting differs from room to room.
I created the gallery in Blender, so maybe creating environment maps for each room in Blender and using MeshStandardMaterial is the way to go?
I use a single ambient light for the artwork at the moment and nothing else.
Here is a live version of the gallery.
Any help is appreciated. Thanks!
Great work on your gallery, controls are very intuitive and overall concept is very well executed, congrats.
Regarding to “better blend in” unlit artwork and a shadow/light baked scene:
-
Light probes can help you in modulating the incoming light. You are right in that creating env maps for each room will better fit the irradiance contribution, but you will have to link the artwork and the corresponding envmap by hand as there is no mechanism -yet- to asign it automatically. Also, please keep in mind that envmaps were created for “distant” surroundings, not nearby walls; a simple solution for this is to use a blurred version of your maps (that don’t break the illusion), and to distribute them in strategic positions:
-
Likewise, you would definitely would improve the effect by not only taking the light contribution into account but also the shadow. In the following image, you can see the paintings are just too bright -almost like being projected onto the walls. One of the key principles of PBR is energy conservation, meaning that reflected light by any surface cannot be more than incoming light. In order to solve it, you could generate “shadow maps” during baking process, that multiplied by the artwork shader should keep the brightness within plausible values
1 Like
Forgot to mention:
An AO can make a great companion to blend in artwork and rooms.
You can implement it like a “shadow catcher”; even better if its already baked to increase performance. In the following picture, left is current, right is with an AO texture mapped onto a transparent plane (plus some subtle GI on top of the painting for a cheap irradiance effect)
1 Like
Thank you, I’m glad you like it.
All your input has been really helpful. I assigned a path string to each wall pointing to its relevant envmap. When I drop an artwork onto a wall, I now also load the envmap and assign it to the MeshStandardMaterial, fixing the “no assignment mechanism” problem.
At this point I realized that although it gets the job done, it’s overkill considering that the material has a roughness of .85, the lighting is pretty flat with very little variation, and the object is a box with only 5 visible faces pointing in 5 directions.
I discovered that the texture .map color can be modulated by the .color property, I decided to give it a try and compare the two:
The one on the left uses an envmap, the one on the right I set the .color value to 0xbbbbbb.
I think the .color solution is similar to what you mentioned about energy conservation by limiting the brightness of the textures, no? It’s not necessarily a shadow map, but I think I could use the assignment mechanism I already implemented to give each wall an array of colors (one for each face of the artwork object) that will be used to control the brightness of our objects. With just using colors and not envmaps I’ll also be saving a lot on resources and fetch requests that I would no longer have to make to get envmaps integrated.
1 Like
Can you elaborate on how you did the AO effect? I really like the results but I’m not sure how to implement it.
That’s a very sharp observation, congrats again!
In fact some developers had already realized this and it is being used to make calculations more efficient. Sébastien Lagarde summed it up in a paper (keep an eye on that blog entry, these are very valuable findings):
“The exact content of a cubemap matters less than its average color and intensity. So we want to make some modifications to an original cubemap to match the lighting environment at a given location. These modifications allow us to reuse a cubemap in several locations instead of generating a new cubemap for each new location.”
Now, the fact that the .color property is available simplifies the implementation quite a bit, I can see that the approach you are already using could be carried over to the whole gallery. In any case, keep an eye on the lighting of the interior room, as it has some light inlets that probably require a combined approach:
The soft shadow is simple, just a plane with a baked AO texture attached to the ‘frame’, which in turn is a cube that holds the actual artwork in only one of its sides. Remember to use .transparent= true in the AO plane material and a png texture with transparent background (although you should get the same results with a jpg+white bg and setting the blending function to ‘multiply’ with underlaying wall material)
I made a quick codepen for you to try, hope it helps:
2 Likes
What I ended up doing is rendering a blank canvas model with a roughness of .85 in blender for each wall that I could place artwork on. Then I simply sampled the resulting colors for each side of the canvas to use in my three.js scene.
This let me get the proper hue, however I did raise the lightness values just based on my own preference. While I am aiming for realism, I modified the lightness in favor of values that simply ‘read’ better on screen, even if they weren’t completely accurate.
I am really happy with the results so far
Thank you for the explanation, I understand how you did this now
How could I adapt this solution to the case where the uploaded artwork is of a variable size and ratio though?
What I came up with is:
- Start with an AO texture with a square ratio.
- Stretch the texture in either x or y direction to match the ratio of the uploaded artwork.
- Scale the AO texture so that where the shadows begin is aligned with where the artwork ends. (The artwork is a 1:1 match with the empty space in the center of the AO texture).
I think to do this would require just knowing the relationship between percentage and pixels the empty space in the center of the AO texture represents and matching that with the size of our artwork. So let’s say our artwork is 1000x800 pixels, and we know that the center of the AO texture is exactly 80% of the texture, then the AO texture should be of size 1000 pixels / 80% = 1250 pixels wide
and 800 pixels / 80% = 1000 pixels tall
.
1 Like