High texture count

They are all in 4096x4096 resolution .jpg/png which I know is bad, but I wanted to have cool graphics :stuck_out_tongue:

I don’t get why dds’ing should only reduce the loading time. I thought dds is some GPU memory friendly but compressed image whereas jpg’s get stored on a per-pixel-base?
Or rather: what could be wrong that dds makes it faster? (Maybe because the files are mip-mapped and save memory?)

But: my assets.jar has 180MiB. Even uncompressed that should be less than the GPUs 1.5GB Memory.
On the other hand I know that there are only several (10?) GL_TEXTURE0 … GL_TEXTUREN

Dds is readable by GPU in its compressed form, while jpg and png are not. Compressed jpg needs to be uncompressed and saved in memory as a raster, it needs 24bits per pixel. Same with png, but there you’ll have 32bits per pixel (8 extra bits are alpha channel).

Reduce the textures resolution to the absolute minimum. Don’t tell me that you need to have 4096x4096 for NPC.
Again, reduce the NPCs count. There is a bottleneck somewhere, try to find it.

I now checked it: The 4096x4096 are only the ones I use for walls (too high anyway).
The MakeHuman one’s are either 2048 or 1024.

I am now giving DDS a try and we will see what happens. Could I manually set a “Highest MipMap” to see which resolution I’d possibly go for? (Without the need to redo the texture everytime).

PS: If I reduce them to 10 NPCs I get reasonable 25 FPS.

Edit: I am ashamed. I only measured the CPU load whilst the Game didn’t have Focus.
I now used the profiler to change some bad designed Controls. Whilst programming them I didn’t see their impact, but it sums up.

Beside that, you don’t see the cpu overhead from the driver. If you want to profile in depth you have to use api trace or a similar tool that allows tracing the gl calls.

But as a general rule of performance bottleneck:
Object count hits way!!! more then vertex count.

Buffer updates are also not that cheap as it might seem. GeometryBatchFactory > SimpleBatchNode > BatchNode

I didn’t read all of the advices you’ve been given, but reducing the triangle count can definitely help.
But IMO here the bottleneck is animating the 50 characters on the CPU (would explain why your GPU idles.)

And that’s what you need to dig into. Sofware skinning will update the animations of your characters on the CPU by updating the mesh’s position buffer on every frame. It can strees the CPU pretty fast if you have a lot of characters.
Hardware skinning will send the transforms of each vertex to the GPU and the transformation will take place in the vertex shader.

Here it can help a lot in your scene so it worth the try.
to enable hardware skinning on a model :

model.getControl(SkeletonControl.class).setHardwareSkinningPreferred(true);

This will enable hardware skinning if your hardware supports it.

I am sorry for the confusion guys,
I made the mistake to post some related Information into my other thread (even though it would belong here).

Conclusion: I currently have a high “overhead” of the animation .reset() (which recursively loops through the bones) even though I am not using the animation. (1500 FPS vs 80 FPS).

This should be doable just as Hardware Skinning is, if I am right? (But I guess JME is not doing it because even with Hardware Skinning on, I have the CPU Load).

Is there a way to do this? (To cancel resets on culled characters)?
And is there another thing like Hardware Skinning as it improved the situation very well?

I now have 25 FPS whilst drawing them and 40 FPS without (so the sole CPU-Update time). (33% GPU Stress, 40% CPU usage)

Edit: with object count you mean the Geometry count? I only wonder how as I can’t batch Animated objects I guess. And the characters wont look the same

Your screenshots show an object count of ~600, which seem to be a lot for that scene, because of that i tought that could be an issue.

But if you can trace your issue to the animations, than thats the place where you should start.

as soon as you have a SkeletonControl it updates the mesh on each frame even if you are in the rest pose.

Either you didn’t do it as it should (I mean activating it), either your hardware doesn’t support it (but it should pop a warning in the console), either you have something else that is causing the strain on the CPU.
With Hardware skinning enabled you won’t have the reset called.

See TestHardwareSkinning in the git repo.

Try to write your own AnimControl, copy all the code and try to do some things in your way.
If it is impossible or too hard then you can make your own control, remove animcontrol and skeletoncontrol from spatial and keep them inside your control, call them only when you need.

I don’t know if these solutions are clean but in the nearest future I’ll do something similar for my own game.

Oh okay, so I need to look further in that.

My Hardware is openGL 4.x (GLSL 1.5) compatible and it Shows in console that is enabled (or atleast prefered).

I might be missing out some skeletons, I need to look into that.

Btw: multiple skeletons per char are senceless overhead aswell?

Edit: I double checked it, I have a SceneGraphVIsitor on the Spatial and for every SkeletonControl it finds, it uses .setHardwareSkinningPreferred(true); but still I get reset and updateWorldvectors calls

Edit: Mai 03, 2015 10:19:58 PM com.jme3.animation.SkeletonControl controlRender
Information: Hardware skinning engaged for Feter_Pramton:tongue01 (Node)

Engaged means “supported by Hardware”?

@nehon:
I just took a look into SkeletonControls’ Source-Code.
My problem is that I have multiple SkeletonControls which seems to be wrong?

Can I manually add a SkeletonControl on the Main-Node? SourceCode says it would automatically scan and attach the targets, but I don’t know what Skeleton to supply.

I don’t know If i could use one random Skeleton of my SubMeshes or if I’d have to “join” them somehow?

That’s weird indeed. so for one character you have multiple armatures right?
How do you import your models? (from blender? with ogre workflow?)
Imo the best thing to do is to edit the armatures in blender so that there is only one for a model.

I’ve recently noticed some weird behavior of clone().
Cloning a spatial with several geometries, particles and particleControls results in additional particle controls in created spatial.

@Darkchaos: do you use clone() ? Check if the source model have proper skeletonControls and if the colne’s result have the same.

Here I have two images.
I use some clone() but this is way before cloning and I guess I am only cloning Vector3f aswell.

It’s using BlenderImporter and in Blender I also only have one Armature.
I tried to Join the Meshes but then I don’t seem to have seperate Geometry anymore (as I need them to switch the clothes dynamicall on/off).

You can also download the blend file from the 3.1 bug thread to see it.

I could “fix” the problem with the multiple SkeletonControls and it improves the performance really well, reset is still consuming quite some CPU.

There is no check made to stop reset when HW is enabled.
On the other hand it seems necessary to correctly apply the Animation?

btw: I guess you don’t have that part in controlRender to be consistent? (When a player is looking away and on again, the animation should have processed, not “paused” somewhat)

Yeah reset skeleton is needed even for HW skinning. That’s the reset of the buffer that is not needed. I though you were talking about this one.

I don’t understand your question

Well I thought you could make those Calls culling sensitive, because you don’t need a walk animation when it’s culled.

However for some Animations which take long (a Monster which evolves or a any complex process) the animation should be played, so you can’t have it culled.

I think I might need my own control for it (CulledAnimationControl) I only wonder how I could “cast” an existing AnimationControl into my derived class?

Edit: Something like this in AnimControl:

private boolean animateOnCulled = true;
public void setAnimateOnCulled(boolean b)
{
    animateOnCulled = b;
}

public void controlUpdate(float tpf)
{
    if (!animateOnCulled)
      return;
    // original code
}

public void controlRender(float tpf)
{
    if (animateOnCulled)
        return;
    // The same code as in controlUpdate.
}

The thing is, if I have say 150-200 spatials being animated and roughly half of them is behind me, this stresses the CPU unnecessarly.

The question is, if such a change is wanted, though, because most people will neither care nor really profit for that.
And if you have some animation (like a castle’s bridge being opened) which takes long, you would notice that the animation does not take place in the backgound.

mhh… Skinning models when they are culled seems unnecessary indeed…
@Momoko_Fan what do you think? Isn’t there some corner case where it’s useful?

There is, imagine you are watching a slow animation, don’t know, a driving train or a catapult being tensioned.

When you look away and then look again, you’d expect it to be moveD.

Or An animation which would move itself in the field of view and hence become unculled.

Thats why I used a boolean.

Actually it is possible to do this while keeping track of time.
The contents of controlUpdate in AnimControl need to be moved to controlRender, then make sure it only runs once in a frame (same way as SkeletonControl does it).
To keep track of time that passed while the model was culled, you need to be able to detect controlUpdate invocations that were not followed by a controlRender invocation, and have some sort of “accumulated time” variable.

1 Like