Jump to content

Static lights decreases fps


Go to solution Solved by Josh,

Recommended Posts

Posted

Code from https://www.ultraengine.com/learn/Entity_Staticize?lang=cpp

Added fps counter to title, disabled VSync, fixed mover include

Release mode 2500-2580 fps, hit space to make light static - 1700-1800 fps

#include "UltraEngine.h"
#include "Components/Motion/Mover.h"

using namespace UltraEngine;

int main(int argc, const char* argv[]) {
    //Plugin for texture loading
    auto plugin = LoadPlugin("Plugins/FITextureLoader");

    //Get display
    auto displays = GetDisplays();

    //Create window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_TITLEBAR | WINDOW_CENTER);

    //Create framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create world
    auto world = CreateWorld();
    world->SetAmbientLight(0.1);
    world->RecordStats(true);

    //Create camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.25);
    camera->SetPosition(0, 2, 0);
    camera->Move(0, 0, -5);

    //Build scene
    auto tunnel = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/tunnel_t.glb");
    tunnel->SetRotation(0, 180, 0);
    tunnel->Staticize();

    auto cage = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fancage.glb");
    cage->Staticize();

    auto fan = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fanblades.glb");
    fan->SetPosition(0, 2, 0);
    auto mover = fan->AddComponent<Mover>();
    mover->rotationspeed.z = 300;

    auto light = CreatePointLight(world);
    light->SetColor(2, 2, 2);
    light->SetRange(10);
    light->SetPosition(0, 2, 2);
    light->SetColor(4.0);

    //Display text
    auto orthocam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    orthocam->SetClearMode(CLEAR_DEPTH);
    orthocam->SetRenderLayers(128);
    orthocam->SetPosition(float(framebuffer->size.x) * 0.5, float(framebuffer->size.y) * 0.5f);

    auto font = LoadFont("Fonts/arial.ttf");

    auto text = CreateSprite(world, font, "Shadow polygons: 0", 14.0 * displays[0]->scale);
    text->SetPosition(2, framebuffer->size.y - 16.0f * displays[0]->scale);
    text->SetRenderLayers(128);

    auto text2 = CreateSprite(world, font, "Press space to make the light static.", 14.0 * displays[0]->scale);
    text2->SetPosition(2, framebuffer->size.y - 16.0f * 2.0f * displays[0]->scale);
    text2->SetRenderLayers(128);

    //Main loop
    while (!window->KeyHit(KEY_ESCAPE) and !window->Closed()) {
        world->Update();
        world->Render(framebuffer, false);
        window->SetText("FPS: " + String(world->renderstats.framerate));

        if (window->KeyHit(KEY_SPACE)) {
            light->Staticize();
            text2->SetHidden(true);
        }

        text->SetText("Shadow polygons: " + String(world->renderstats.shadowpolygons));
    }
    return 0;
}

 

Check out Slipgate Tactics demo, which is made with Ultra Engine/Leadwerks 5:

https://www.leadwerks.com/community/topic/61480-slipgate-tactics-demo/

Posted

There are two opposing factors:

  • Static lights don't have to render as much geometry when a shadow is updated, because they store a a shadow map for all the static objects.
  • The static shadow map has to be copied to the dynamic shadow map at the start of the shadow update.

In situations where you have a small amount of dynamic geometry and a large amount of static geometry, like a single character walking through a room made up of a lot of polygons, then a static light will perform faster because it only has to render the character to update the shadow.

However, that texture copy does incur a cost, and it could be possible in some situations that cost would be greater than the savings you get by skipping the static geometry, even though fewer polygons are being drawn.

I don't know if that is the case here. I will test this against 0.9.7 and check to see if they produce the same result.

Let's build cool stuff and have fun. :)

  • 1 month later...
  • 1 month later...
Posted

Okay, so the cost of the static texture copy is greater than I expected. You can overall faster speed this way in some situations, but you have to be saving a lot of shadow polygons. Higher-resolution shadows are much more expensive to copy and will offset the savings you get from not rendering a lot of extra polygons.

In this test I used a spotlight and created an extra 5,000,000 polys in the scene that don't have to be drawn in the shadow when it goes static.

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[]) {

    //Get display
    auto displays = GetDisplays();

    //Create window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_TITLEBAR | WINDOW_CENTER);

    //Create framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create world
    auto world = CreateWorld();
    world->SetAmbientLight(0.1);
    world->RecordStats(true);

    //Create camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.25);
    camera->SetPosition(0, 2, 0);
    camera->Move(0, 0, -5);
    camera->SetRenderLayers(1);

    //Build scene
    auto tunnel = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/tunnel_t.glb");
    tunnel->SetRotation(0, 180, 0);
    tunnel->Staticize();

    auto cage = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fancage.glb");
    cage->Staticize();

    auto fan = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fanblades.glb");
    fan->SetPosition(0, 2, 0);

    //auto light = CreatePointLight(world);
    auto light = CreateSpotLight(world);
    light->Turn(0, 180, 0);
    light->SetColor(2, 2, 2);
    light->SetRange(15);
    light->SetPosition(0, 2, 2);
    light->SetColor(2.0);
    light->SetRenderLayers(1 | 2);
    light->SetShadowmapSize(1024);

    std::vector<shared_ptr<Entity> > instances;
    instances.reserve(1000);
    auto base = CreateSphere(world);
    base->SetCollider(NULL);
    base->SetRenderLayers(2);
    for (int n = 0; n < instances.capacity(); ++n)
    {
        auto inst = base->Instantiate(world);
        inst->SetPosition(0, 0, -10);
        inst->Staticize();
        inst->SetRenderLayers(2);
        instances.push_back(inst);
    }

    //Main loop
    while (!window->KeyHit(KEY_ESCAPE) and !window->Closed()) {

        if (window->KeyHit(KEY_SPACE))
        {
            light->Staticize();
        }

        world->Update();
        world->Render(framebuffer, false);
        window->SetText("FPS: " + String(world->renderstats.framerate) + " Shadow polys: " + String(world->renderstats.shadowpolygons) + " Scene polys: " + String(world->renderstats.polygons));

        fan->Turn(0, 0, 1);
    }
    return 0;
}

 

Let's build cool stuff and have fun. :)

Posted

You will also see an overall savings if the shadow resolution is low, like in this test. I did not create extra polygons, and just the simple scene runs faster with a static light when the shadow resolution is set to 256.

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[]) {

    //Get display
    auto displays = GetDisplays();

    //Create window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_TITLEBAR | WINDOW_CENTER);

    //Create framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create world
    auto world = CreateWorld();
    world->SetAmbientLight(0.1);
    world->RecordStats(true);

    //Create camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.25);
    camera->SetPosition(0, 2, 0);
    camera->Move(0, 0, -5);
    camera->SetRenderLayers(1);

    //Build scene
    auto tunnel = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/tunnel_t.glb");
    tunnel->SetRotation(0, 180, 0);
    tunnel->Staticize();

    auto cage = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fancage.glb");
    cage->Staticize();

    auto fan = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fanblades.glb");
    fan->SetPosition(0, 2, 0);

    //auto light = CreatePointLight(world);
    auto light = CreateSpotLight(world);
    light->Turn(0, 180, 0);
    light->SetColor(2, 2, 2);
    light->SetRange(15);
    light->SetPosition(0, 2, 2);
    light->SetColor(2.0);
    light->SetRenderLayers(1 | 2);
    light->SetShadowmapSize(256);

    //Main loop
    while (!window->KeyHit(KEY_ESCAPE) and !window->Closed()) {

        if (window->KeyHit(KEY_SPACE))
        {
            light->Staticize();
        }

        world->Update();
        world->Render(framebuffer, false);
        window->SetText("FPS: " + String(world->renderstats.framerate) + " Shadow polys: " + String(world->renderstats.shadowpolygons) + " Scene polys: " + String(world->renderstats.polygons));

        fan->Turn(0, 0, 1);
    }
    return 0;
}

 

Let's build cool stuff and have fun. :)

Posted

I also discovered that the default world shadow quality setting is making all shadows twice as high-res as they are defined to be, by default. This is certainly going to skew our results...

Let's build cool stuff and have fun. :)

  • Solution
Posted

In the next build you will probably see a small increase with the default example. The savings gets a lot more when the scene is more complex.

The primary issue is our shadow maps are too big. I fixed the default world setting and I am making the default size 512x512 for point, spot, and box lights, the same as it was in Leadwerks 4.

  • Like 1

Let's build cool stuff and have fun. :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...