BakeLighting questions


photo

Recommended Posts

Hello,
I have somes questions for the BakeLighting.
When I use Unigine::BakeLighting::getProgress() the returned value doesn't work all the time.

Sometime the returned values like this :

6-6-6-6-6-6....20-20-20-20-20-20....86. The 100% is never returned ?


I have tested with a big size (setBoxSize ) of LightVoxelProbePtr and I have one error "can't create texture3D", what's the limit size please ?
Thanks.

Edited by fabre.cedric
Link to post

Hello,

Could you please provide a small sample with BakeLighting::getProgress problem demo?

The maximum possible size of a texture can be obtained with Render::getMaxTextureBufferSize(). It depends on your GPU. And you can get expected texture size for specific parameters with the static method Texture::getVideoMemoryUsage. 

Link to post

Hello,
You can write in the AppQt.cpp (viewportQt sample) in the update_engine function  :
 

    if (Unigine::Input::isKeyUp(Unigine::Input::KEY_A))
    {
        Unigine::LightVoxelProbePtr lightVoxelWorld = Unigine::LightVoxelProbe::create();
        lightVoxelWorld->setBoxSize(Unigine::Math::vec3(1.2f, 1.2f, 1.2f));
        lightVoxelWorld->setWorldPosition(Unigine::Math::vec3(0.0f));
        lightVoxelWorld->setColor(Unigine::Math::vec4(1, 1, 1, 1));
        lightVoxelWorld->setVoxelSize(0.3f);
        lightVoxelWorld->setBakeVisibilityLightOmni(true);
        lightVoxelWorld->setBakeVisibilityLightProj(true);
        lightVoxelWorld->setBakeVisibilityLightWorld(true);
        lightVoxelWorld->setBakeVisibilityVoxelProbe(true);
        lightVoxelWorld->setBakeVisibilitySky(true);
        lightVoxelWorld->setBakeVisibilityEmission(true);
        lightVoxelWorld->setBakeVisibilityLightmap(true);
        lightVoxelWorld->setAttenuationDistance(Unigine::Math::vec3(1.0f));
        lightVoxelWorld->setAttenuationPower(1.0f);
        lightVoxelWorld->setUseSunColor(false);
        lightVoxelWorld->setReflectionEnabled(true);
        lightVoxelWorld->setAmbientBias(0.05f);
        lightVoxelWorld->setAmbientCubicFiltering(true);
        lightVoxelWorld->setGrassInteractionEnabled(true);
        lightVoxelWorld->setBakeInternalVolume(Unigine::LightVoxelProbe::BAKE_INTERNAL_VOLUME_FULL);

        //If not called, the baking never start ???
        Unigine::Engine::get()->update();
        Unigine::Engine::get()->render();
        Unigine::Engine::get()->swap();
        //-------------------------------------------------

        Unigine::BakeLighting::setVoxelSizeMultiplier(1.0f);
        Unigine::BakeLighting::setBounces(0);
        Unigine::BakeLighting::setSamplesPerFrame(10);
        Unigine::BakeLighting::bakeAll();
    }

    if (Unigine::BakeLighting::isBaking() == true)
    {
        Unigine::Log::warning("Progress : " + Unigine::String::itoa(Unigine::BakeLighting::getProgress()) + "\n");
    }



The returned value like this in my log :
WARNING:    Progress : 15
WARNING:    Progress : 31
WARNING:    Progress : 46
WARNING:    Progress : 62
WARNING:    Progress : 78
WARNING:    Progress : 93
    Bake Lighting Bounce: 1/1 Elapsed time: 0.231

Link to post

So, you will never receive 100% since job is done.

Instead of it you get time spent message - "Bake Lighting Bounce: 1/1 Elapsed time: 0.231" which is mean task is complete correctly

Link to post

int getProgress ( ) const#
Returns overall progress of light baking.

For me this is not logical, the getProgress must return the progress from 0 to 100 to draw a real progress bar for User.
If the getProgress never return 100, how this is possible to know when the task is completed in C++ code ?

Link to post

Truth be told there is no callback in API to get know baking is over. Even in Editor we do not ever display 100% just closing progress bar when processes are done.

On 3/12/2021 at 3:19 PM, fabre.cedric said:

If the getProgress never return 100, how this is possible to know when the task is completed in C++ code ?

If isBaking returned false

Or use a flag to track the process

bool is_baking_started = true;

if (Unigine::BakeLighting::isBaking())
{
        Unigine::Log::warning("Progress : " + Unigine::String::itoa(Unigine::BakeLighting::getProgress()) + "\n");
}
else if (is_baking_started)
{
	  Unigine::Log::warning("Progress : 100%\n");
	  is_baking_started = false;
}

 

Link to post
Posted (edited)

This method doesn't work because when the Baking is finished (isBaking() =0)  I save all textures from probes and lights in another Folder and the textures are corrupted.
If I wait after 10 seconds for exemple that work, but I think this is not a proper method !
 

Edited by fabre.cedric
Link to post

And can you explain please why when I want to start baking I must call engine update,render and swap ?
I don't understand where is the problem with this too ?

Link to post

Hi Fabre,

Thank you for the waiting.

The light baking API was not designed to be public available initially, but after studying other engines on the market we thought that it would be a nice addition to have. Writing your own baking tool is doable task, but it can take months to develop.

As far as I understand you already have baking working on your side, so only two minor things needs clarifications:

  1. Understand why there is need to call update() / render() / swap()
  2. Find out when it's safe to save the textures

In order to give you useful feedback we need to check your exact execution sequence in the real application. When and how your code is called is critical to understand the root cause. Maybe there is an issue with calling from non-main thread or some kind of Qt-specific stuff. Once we would have the 100% the same behavior reproduction on our side we can tell how to fix it.

Regarding the first issue: we indeed can reproduce it by placing the code in update_engine(), but that's not the correct usage. Custom user logic should be placed in doUpdate() method. Doing this will not require manual call for update() / render() / swap() because everything is called automatically. Something like that:

void AppQt::doUpdate()
{
	CustomApp::update();

	if (Unigine::Input::isKeyUp(Unigine::Input::KEY_A) && !Unigine::BakeLighting::isBaking())
	{
		Unigine::LightVoxelProbePtr lightVoxelWorld = Unigine::LightVoxelProbe::create();
		lightVoxelWorld->setBoxSize(Unigine::Math::vec3(1.2f, 1.2f, 1.2f));
		lightVoxelWorld->setWorldPosition(Unigine::Math::vec3(0.0f));
		lightVoxelWorld->setColor(Unigine::Math::vec4(1, 1, 1, 1));
		lightVoxelWorld->setVoxelSize(0.3f);
		lightVoxelWorld->setBakeVisibilityLightOmni(true);
		lightVoxelWorld->setBakeVisibilityLightProj(true);
		lightVoxelWorld->setBakeVisibilityLightWorld(true);
		lightVoxelWorld->setBakeVisibilityVoxelProbe(true);
		lightVoxelWorld->setBakeVisibilitySky(true);
		lightVoxelWorld->setBakeVisibilityEmission(true);
		lightVoxelWorld->setBakeVisibilityLightmap(true);
		lightVoxelWorld->setAttenuationDistance(Unigine::Math::vec3(1.0f));
		lightVoxelWorld->setAttenuationPower(1.0f);
		lightVoxelWorld->setUseSunColor(false);
		lightVoxelWorld->setReflectionEnabled(true);
		lightVoxelWorld->setAmbientBias(0.05f);
		lightVoxelWorld->setAmbientCubicFiltering(true);
		lightVoxelWorld->setGrassInteractionEnabled(true);
		lightVoxelWorld->setBakeInternalVolume(Unigine::LightVoxelProbe::BAKE_INTERNAL_VOLUME_FULL);

		Unigine::BakeLighting::setVoxelSizeMultiplier(1.0f);
		Unigine::BakeLighting::setBounces(0);
		Unigine::BakeLighting::setSamplesPerFrame(10);
		Unigine::BakeLighting::bakeAll();
	}

	if (Unigine::BakeLighting::isBaking() == true)
	{
		Unigine::Log::warning("Progress : " + Unigine::String::itoa(Unigine::BakeLighting::getProgress()) + "\n");
	}
}


Regarding the second issue - we also need to check the reproduction first. Maybe moving code from update_engine will somehow fix this behavior as well.

 

Frankly speaking ViewportQt sample needs some refactoring, because some things like doUpdate() are not always obvious, but very critical for correct work. I will add a task do update ViewportQt sample usage so it would reflect current state of the recommended Qt integration pipeline.

Please let us know if you will get better results after applying our recommendations.

Thanks!

  • Thanks 1
Link to post

Hi,
My function to start bake rendering is called from a QT button.
I have just copy/paste this method to widgetViewportQt sample for reproduce the same state for debug purpose.

If calling update/render/swap can't cause crashs or other, this is not a problem for now.
I just want to understand how that work and why and you have perfectly explained this.

For saving baking textures, I'll try to displace calling method to doUpdate !
Thanks and have a good day.

Link to post
  • 4 weeks later...

Hello,
In the 2.14 sdk when I call : Unigine::BakeLighting::bakeAll(); Nothing happen.
Have you changed anything between 2.13.0.1 and 2.14 ?
Thanks

Link to post

Hi Fabre,

Execution sequence has been slightly altered, but the light baking process is working fine in the Editor (without any code changes from our side).

From where do you call bakeAll() - can you reproduce this behavior when calling from doUpdate()?

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

Hi Silent,

I can reproduce this behavior in the sample viewportWidgetQt when calling bakeAll() in doUpdate in AppQt.cpp like bmyagkov explanation.
 

I have tried to call the other method "bake" with "lightVoxelProbe" and "light" lists and the baking process appear to work correctly.
Unigine::BakeLighting::bake(lightVoxelWorldList, emptyListLightEnvironmentProbes, lightList, emptyListObjectMeshStatic, emptyListSurfaces);


Thanks

Link to post
Posted (edited)

Are you sûre the lightmap baking process is started ?
I have the same result but the lightmap baking doesn't start, I think you can view only the lightVoxelWorld in your video ?
Can you try to change the size of the voxel with this for exemple ? :
 

lightVoxelWorld->setBoxSize(Unigine::Math::vec3(10.2f, 10.2f, 10.2f));

Look at the log, there is no line that correspond to :

Unigine::Log::warning("Progress : " + Unigine::String::itoa(Unigine::BakeLighting::getProgress()) + "\n");
Edited by fabre.cedric
Link to post

I think you can view there is a problem with bakeAll method like this
Try with setBoxSize(10,10,10) and this code" just for testing, I know this is not really beautiful :)"

        //Unigine::BakeLighting::bakeAll();

        Unigine::Vector<Unigine::LightVoxelProbePtr>listvoxel;
        listvoxel.push_back(lightVoxelWorld);
        Unigine::Vector<Unigine::LightEnvironmentProbePtr>listenv;
        Unigine::Vector<Unigine::LightPtr>listlight;
        Unigine::Vector<Unigine::ObjectMeshStaticPtr>listobject;
        Unigine::Vector<int>listsurf;

        Unigine::BakeLighting::bake(listvoxel, listenv, listlight, listobject, listsurf);

Link to post

It looks like there is simply no objects on a scene with enabled lightmaps option.

If you will enable this option for a material ball (for example) you will see the progress again in engine log. Here is the option that you need to enable on surfaces to make lightmaps baking process to work as expected:
image.png

More info on this parameters you can find in the documentation:

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

Ok,
Can you explain why the process start with bake and not bakeAll() like my video please, because I don't have changed the "lightmaps" flag ?
Thanks :)

Link to post

In order to bakeAll() method to work as previous you need to explicitly add this object to the Editor after creation:

lightVoxelWorld->setShowInEditorEnabled(true);

 

On a side note:  the lights baking process from the Engine API will continue to be more complex with the future SDK updates (namely: atlases support, directional lightmaps, node references & batching support and many other things). Therefore more logic for preparing the data for the baking tool will be transferred into the Editor part. More likely there will be no bakeAll() method at all by the end of this year (but it's not 100%), since the baking process will be much more complicated. In worst case scenario whole light baking API will be even removed from API because it would be impossible to use without the Editor at all.

It's working right now because current lightmaps implementation is very simple and allow us to do such things. If we want to improve performance, reduce baking times, provide more features (like directional lightmaps, for example) it will require more complex steps in data preparations that can't be done alone on the Engine side.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

Hi Silent,

What's the right way if I want to maintain our software with Unigine always up to date ?

I don't understand why you have made this class accessible to your users if this is to remove it from future release :-/ .

Thanks.

Link to post

Yeah, we thought it was a good option to have in API (until we started further research after the initial release). In order to make an updated API to produce a good results you will probably need to emulate Editor behavior in some way (provide texture atlases, .*meta files from disc that engine may expect to see and so on). Some of the emulation processes may be trivial, but some parts may be very tricky (or nearly impossible to achieve).

The important thing here is that all of these changes will not come at once in the next release, so you still can use existing API for long period of time (1y+) and get the engine updates as usual.

Thanks!

 

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post