Multiply exr lightmap in Reality Composer Pro Shader Graph

I’m trying to use EXR lightmaps to overlay baked lighting on top of a base texture in the RCP Shader Graph.

When I multiply an EXR image set to Image(float) with an 8-bit base texture, the output becomes Image(float). I can’t connect that to the BaseColor input on the UnlitSurface node, since it only accepts Color3f.

I expected to be able to use a Convert node between the Multiply node and the BaseColor input, but when I do that, the result becomes black and white instead of the expected outcome: the EXR multiplied with the base texture using a baseline value of 1, where values below 1 in the EXR would darken the base texture and values above 1 would brighten it.

Is there any documentation on how to properly overlay a 32-bit EXR lightmap in the RCP Shader Graph, or is the black-and-white output from the Convert node a bug?

Hello @psqv , thank you for your question!

Can you share more about what exactly you're trying to do? I want to make sure I understand correctly so the answer I give is useful.

The first thing that may be going wrong is that you say you are sampling the Image using Image(float), which only gives you one channel, and then multiplying that with a Color3f. I suspect you need to modify the Image node to be Image (Color3f) as well. You can set this in the inspector for the node in Reality Composer Pro.

Your description of your baked lighting setup sounds unusual to me. It sounds like you are trying to multiply the color of two textures together in the same material. This should be possible (the sampling mode on your image node might be causing it to break), however I don't think this is the correct way to handle baked lighting. Baked lighting only needs one texture, your base color texture, that already contains all your shadows and highlights.

Ultimately, your baked lighting shader graph should look like this:

[Image] --> [Unlit Surface] --> [Outputs]

Of course you can add extra features to the shader, we added a lot of extra stuff to our so-called "unlit" shader in Petite Asteroids, but the core concept should be the same. There's also a presentation from last month on our official YouTube channel that explains how to setup an unlit Shader Graph: https://www.youtube.com/live/leGqoF8HJxU?si=3Oslac8d1hMIqHEb&t=17398. The relevant section starts at around 4 hours, 49 minutes, and 58 seconds into the stream.

Let me know if you have any more questions!

Hello,

Thank you for the quick and in-depth reply. I will dig into the "unlit" shader for Petite Asteriods and see if I can modify it to suit my needs.

I will do my best try to explain what I am trying to do in more detail.

My plan is to separate BaseColor texture and baked light and use a tiling UV set (st) for BaseColor and an unwrapped non-overlapping UV (st1) set for the baked lightmaps. This way texture resolution (and the surface detail) will not be dictated by the lightmap resolution, allowing for closeup viewing of surfaces without losing detail, while preserving the baked light for shading. This would allow for creating much more realistic environments that take advantage of the fantastic resolution of the VisionPro, combined with beautiful prebaked light. This is the way baked light works in Unity and Unreal Engine.

I was expecting to be able to do this by baking out the lightmaps as exr with base 1, so that dark areas of the lightmaps would, when multiplied with the BaseColor texture darken the areas where the exr has values below 1 and brighten areas where exr exposure is above 1.

If I convert he lightmap exr to color3f, then I lose the dynamic range of the exr and a multiply operation will only darken the BaseColor channel, since color3f only has dynamic range between 0 to 1.

So my thinking was that the image node would not sample the exr input as black and white, but rather as rgb with extended dynamic range, and when multiplied with the BaseColor texture the result would be the exr darkening areas with brightness below 1 and brighten areas above 1 with color information retained (because the lightmaps has colored lighting information from both light and environment lighting). After the multiply operation, I would then use convert the output from float to color3f before connecting it to the BaseColor channel in the unlit shader node.

Yesterday I found that there´s a mode in the multiply node called Multiply (Color3f * float) that I thought would do exactly what I want, but since the float output from the exr image node is apparently greyscale, it was also a dead end.

I have tried various other nodes and also multiplying a color3f version of the lightmap on top of the grayscale float lightmap to combine the greyscale float exr info with he color information and reach the desired result, but I cannot seem to figure out how to make this workflow function.

Here´s an image of what I am trying to achieve:

Here´s an image of the current output with the Multiply (Color3f * float) node:

Thanks for the context @psqv , I understand better now what you are trying to do.

Can you try sampling both images, your base color and your light map, using Image(vector3f)? Then multiply those values together, then use a Convert node to convert the product from Vector3f to Color3f before piping the color value into the unlit surface node.

Image(float) will create grayscale because that only samples one channel, so I'd consider what you are currently seeing to be expected behavior.

If using Image(vector3f) does not work, could you please send us feedback using Feedback Assistant, and then share the ticket number here so I can track it down on our end.

Thank you!

Thanks for the quick feedback, super appreciated.

I tested this suggestion, and the result seems to be much closer to what I was expecting. But, to my eyes, it looks like the .exr lightmap loses a lot of dynamic range.

Please see the two images attached below, where the lower sofa uses a normal png texture map where both texture and lighting is baked into the BaseColor texture in Blender, while the upper sofa uses the tiled fabric texture as BaseColor with the exr lightmap multiplied using the Image(vector3f) approach you suggested. The loss of dynamic range in the .exr multiplied as Image(vector3f) is quite apparent.

Multiply exr lightmap in Reality Composer Pro Shader Graph
 
 
Q