ands / lightmapper

A C/C++ single-file library for drop-in lightmap baking. Just use your existing OpenGL renderer to bounce light!
1.41k stars 133 forks source link

Any further documentation ? #17

Closed Nolram12345 closed 1 year ago

Nolram12345 commented 3 years ago

Hello, I am currently looking for a way to bake simple global-illumination lightmaps, and this seems to be the most popular solution for that task. I have been struggling my way around the example application and all available info for a while now, however since I mainly work in C++ some of the C-aspects were unfamiliar to me, and it was generally quite hard to grasp how the library works. Is there any further documentation, absolutely minimal examples or some for baking global illumination and not just Ambient Occlusion ? How can lights be added into the trace and not just a single background color ?

ands commented 2 years ago

Hi @Nolram12345. Sorry for the late response. How can I help you with the struggle? Can you tell me which part of the example you are struggling with? The example is (unfortunately) already fairly minimal. A lot of the code is boiler plate code for loading shaders, simple obj files etc. that are cluttering the C file, but the example can't work without that. I can see how that may be distracting.

The basic idea is that the library traverses your lightmap in UV space and for each pixel that is covered by a triangle it looks up where that position would end up in 3D space and renders half a cube map of the scene at that surface position (the half that points in the positive normal direction). The result of this half cube is integrated down to a single pixel value and output as the lightmap value. (There's some batching going on in the background and ways to reduce the number of rendered half cubes by interpolating, but this doesn't matter for the basic understanding).

From the user of the lib point of view, you let the lib know about your geometry & UVs, then give it a target lightmap buffer and then let the lib do the iteration over the data in a loop, while in each iteration you just render your scene in the way that it should look like to gather the correct lighting information for the lightmap pixel/texel. (See also https://github.com/ands/lightmapper/#example-usage)

So, if you want lights instead of AO in your result, just render emissive objects in your scene (e.g. light bulb objects with a static color. The intensity is allowed to exceed 1.0, 1.0, 1.0) and set the clear color to 0.0, 0.0, 0.0.

I hope that helps :)

Nolram12345 commented 2 years ago

Thank you for the information. This absolutely clears up some things.

Nolram12345 commented 2 years ago

Also, would it be possible to get an example of how to use color/emission with the lightmapper to get colored bounce lighting ?

alexGuntha commented 2 years ago

Hi @Nolram12345 , I too struggled adding actual illumination to the example code, and I tried to make a "minimal" source out of it: https://gist.github.com/alexGuntha/93539a02056deffcf2a0a3f73de798d2 You can use a diff tool to check what has been added to the original example.c, mainly: ->The background color is now black by default instead of white, so that the light from the source is plainly visible ->Additional mesh information for the light source, and the corresponding GL ids ->Creating a texture for the light source (a 1-pixel all-red texture) ->I manage intensity as an additional field in the shader instead of encoding it in the light source's texture, I'm not sure that's the best practice ->drawScene draws both the test model and the light source ->A few tweaks in the .obj loader so that I was able to test more files (Note: to test much bigger meshes I had to switch indices from unsigned shorts to unsigned ints) This is the mesh used for the light source: https://gist.github.com/alexGuntha/ed9f7799a9aa2e7c717ab2351abbce55 This creates a red cube as a light source next to the gazebo. image

Please tell me if I'm giving a bad example in the code above.

Nolram12345 commented 2 years ago

Thank you so much for that. I am currently attempting to build this into my own renderer, so I have already abandoned my attempt at doing this "sample based", but thank you a lot anyways for the resource, it will certainly be useful.

Enemy-77 commented 1 year ago

First of all, thank you for the demo. But a question disturbs me, that is how the lib get the light data to bake the scne? I do not find related code. The reason why I use this lib is that I want to integrate it into my renderer, but I don't understand the theroy behind it. The main problem is that I do not understand how to combine light system in my renderer and this lib. Any one can help me?

alexGuntha commented 1 year ago

Hi @Enemy-77, I also struggled understanding how lights could be added to the scene, that's why after I finally understood I felt the need to make the demo above. There is not a separate concept of light sources, light source should actually be meshes added to the scene, drawn with a color. As you can see in drawScene(), we draw the world using scene->lightmap as the texture, which is originally black so it doesn't emit light, then as the lightmapping process goes on the lightmap texture will be filled with color (if there is a light source in the scene, or a non-zero background color), so the world will be more and more illuminated by light bounces.

When we draw the cube in the demo above, we bind the texture scene->lightColorTexture (which is solid red), so it will emit light in the scene. (it could also be done by drawing it with another shader that has a color set as an uniform.)

Basically, assuming your renderer has colored point lights for example, if you want to bake lights in your scene, you would need to add a colored mesh at each position there should be a point light.

The main benefit of this approach is that lights can be any shape you want.

Enemy-77 commented 1 year ago

@alexGuntha Thank you so much! It helps! But still a problem: You say

Basically, assuming your renderer has colored point lights for example, if you want to bake lights in your scene, you would need to add a colored mesh at each position there should be a point light.

But the colored mesh added to the scene seem weird because there is no such mesh originally, there is some tricks to solve this?

alexGuntha commented 1 year ago

You draw it only when generating the lightmap (in the example, when drawScene is called from bake), not for "actual" rendering (from mainLoop in the example). I left it visible in the demo because there is no other way to identify the source of the light in that scene.

Enemy-77 commented 1 year ago

@alexGuntha It works! Thank you so much!!!