How to improve the performance of SkyBox?

Started by kiffa, March 26, 2013, 08:52:34 AM

Previous topic - Next topic

kiffa

I made a skyBox, which cause a 6-9 fps dropping down。How to improve the performance? Could i use only one world and one-time rendering to make skyBox?

My codes:

World skyWorld = new world();

/ /sky is an object3D which has a center of (0,0,0);
skyWorld.add(sky). 

//set camera to the center of sky.
skyWorld.getCamera().setPosition(0,0,0);

// sceneWorld is the world of scene(the "real" world).
skyWorld.getCamera().setBack(sceneWorld.getCamera().getBack());

// don't write to zBuffer when rendering the sky, to avoid to adjust the size of sky.
sky.setRenderHook(new IRenderHook(){
public void beforeRendering(int paramInt) {
         GLES20.glDepthMask(false);
      }

  public void afterRendering(int paramInt) {
        GLES20.glDepthMask(true);
      }

});

// onDrawFrame(), rendering sky per frame
framebuffer.clear();
skyWorld.renderScene(framebuffer);
skyWorld.draw(framebuffer);

sceneWorld.renderScene(framebuffer);
sceneWorld.draw(framebuffer);

framebuffer.display();
 

kiffa

I tried to add sky to sceneWorld, but the result seems incorrect:


sceneWorld.addObject(sky);

sky.setRenderHook(new IRenderHook() {
    @Override
      public void beforeRendering(int paramInt) {
        mBackPos = sceneWorld.getCamera().getPosition();
        sceneWorld.getCamera().setPosition(0,0,0);
        GLES20.glDepthMask(false);
      }
     
      @Override
      public void afterRendering(int paramInt) {
        GLES20.glDepthMask(true);
        sceneWorld.getCamera().setPosition(mBackPos);
      }
    });
});




When does jPCT-AE calculate and upload the MVP matrix?

EgonOlsen

It makes on sense to add the skybox to the main scene/world. It will cause nothing but more complex code and won't improve performance one single bit. If the skybox slows down things, this is either because of the additional fillrate it requires or because of the texture fetches and cache misses in case that the skybox's textures are pretty large. Rendering itself is really cheap.

kiffa

So, the following 2 codes have the very close performance, right?:

//code 1
world1.add(obj1);
world2.add(obj2);
renderWorld1();
renderWorld2();

//code 2
world.add(obj1);
world.add(obj2);
renderWorld();


Raswr

I'm not a fan of rendering the sky as a first object, I prefer leaving it to the last object. That it because if you draw the sky first without z test, you draw ALL the fragments of the sky, and probably many of them are going to be overwritten by other geometry, making some fragment rendering useless (and expensive if your sky uses some kind of shader).

I usually draw the sky the last with a vertex shader that does this to push the sky back into the far clipping plane, so it seems as it was in the infinity:

vec4 p=modelViewProjectionMatrix * position; //vert to eye space
gl_Position = vec4(p.x, p.y, p.w, p.w);           // replace z by w, this pushes skydome vertex back to the far plane


This way, the sky is pushed back in the far plane (no size issues) and you are rendering it in the last position with z test enabled, so probably many of the sky's fragments are ocluded by other things in your scene and it will be cheaper to render.

Hope I helped.

EgonOlsen

Rendering order shouldn't matter on any mobile device except Tegra, because they are all deferred renderers anyway (....except for Tegra).

Raswr

#7
Quote from: EgonOlsen on March 30, 2013, 08:57:21 PM
Rendering order shouldn't matter on any mobile device except Tegra, because they are all deferred renderers anyway (....except for Tegra).

Interesting I didn't know that, I come from programming desktop OpenGL so that's a good thing to know. Then, sending  the sky to render as the last object with depth test enabled wouldn't give any benefit on a phone (except the Tegra devices)?

I'll try some experiments anyway if I get time :) (both my devices are adrenos)

Thank you for the info.

kiffa

#8
Thanks, Raswr. I will try your method.

In my test, rendering the sky in 2 worlds will cause a fps-down of 5-7(from 54+ to 47+), and the ADT says rendering the sky-world consumed about 9% cpu-time .

If i scale the sky to a large one which can envelop the whole scene, then render the sky in the main world as a normal object  as others, the fps has almost little down.

Maybe there is something wrong in my codes...

Another question, if i want to do the profiling, i can use ADT to do the cpu-profiling, but how to profile the gpu? Between cpu and gpu,  who will kill more performance?

EgonOlsen

I don't see how putting the sky in an additional world can cause a significant hit. Which device are you using for testing?

kiffa

Quote from: EgonOlsen on April 08, 2013, 07:21:42 AM
I don't see how putting the sky in an additional world can cause a significant hit. Which device are you using for testing?

Sorry for the late replying, i was busy these days.

My previous testing is not exact, seems the result was affected heavily by another (app) process. I will test again later. My device:

OS: Android 2.3.3
GPU: NVIDIA Tegra2
OpenGL ES: 2.0
RAM: 1GB
CPU: 1G-2Cores ArmV7