The issue I’m facing right now is that when there are thousands of selectable thininstances in the scene, every mouse down / up event triggers a callback that takes ~ 400-600 milliseconds to execute, so with a full click event, its takes around 1100 milliseconds to execute. I tried the following:
Using a selection octree with the scene after everything is loaded like so: const capacity = 64 const maxDepth = 2 this.selectionOctree = this.scene.createOrUpdateSelectionOctree(capacity, maxDepth)
Setting scene.skipPointerMovePicking = true
(I can’t actually use this option in my project but I wanted to see if it would make a difference)
Just to give you an idea of the methods being invoked that take up the most time I took a chrome profiler snapshot while running my actual app:
I believe that Event: pointerdown callback present in the screenshot ^ is being invoke internally by the ArcRotateCamera class - is this right? My reasoning for thinking so is that I can produce a similar profiler snapshot within a playground scene with just a camera and the models that I built to to emulate what’s happening in my project:
Ideally in game I’ll be able to select a given rock without too much delay but also be able tp pan the camera smoothly while navigating the 3d terrain. My thought process was that since each thininstance is selectable, its own click event coordinates and mesh properties can be used with an octree. Presently an octree sounds like the best route to me though I’m open to suggestions.
Hey folks, just wanted to give a heads up that we do have tasks in the pipeline to improve input overhead and picking. The plan for this is to have perf improvements for input in place by the end of the month and picking changes by end of August. In the meantime, I can use this PG and the info to see if I can pinpoint what could be happening though it might take a bit for me to dig into this because I’m gonna be out of the office for several days starting this week.
And before completing the rendering frame, the following line is called to set back the colors of cubes to the visual color on screen.
renderTarget.onAfterRender = function () {
.....
box.thinInstanceSetBuffer("color", colorData, 4);
}
I have tried it yet. But I guess it will require a custom material with a custom attribute e.g. ‘pickColor’. Then send pickColor in the onBeforeRender call for the thin instances, which instructs customized fragment shader to apply the single color. And unset the pickColor afterwards to render the actual texture for your model.
BTW, what pointer events you are talking about that cause the performance issue? When I open your PG, FPS is already very low without triggering any mouse/keyboard event.
Woah! Definitely did not realize that was what’s happening there in those before and after callbacks. I will definitely try that out!
BTW, what pointer events you are talking about that cause the performance issue? When I open your PG, FPS is already very low without triggering any mouse/keyboard event.
Yes. I assumed it was something internal to the arcrotate camera as well as the other cameras, it only happens when the thininstances are set to be pickable. You’ll notice that in the demo pg you referenced, it does not use thinInstanceEnablePicking = true. So whatever is about that setting it affects cameras by default.
Yes. I assumed it was something internal to the arcrotate camera as well as the other cameras, it only happens when the thininstances are set to be pickable.
I use FreeCamera and implemented my own customized arc rotation. That’s probably why I didn’t encounter this issue. GLHF
No, I didn’t have problem with it. 800 samurai, ~1000 trees, ~100 building blocks, and some rocks. I had problem with picking on mouse hover since mouse move is triggered in high frequency. I was able to get it to an acceptable level by throttling mouse move events, but I will definitely try GPU picking when I have time. For mouse click based picking, I never had performance issue.
Here’s my best attempt at getting this GPU selection method working for my usecase:
You’ll notice the blue-ish rocks, that’s an artifact of not being able to set the color back to what it was originally in the renderTarget.onAfterRender callback method. However because of that it’s visually easy to tell which rocks to test with by hovering the mouse over them and seeing what thininstance is identifed by the GPU selection process.
It’s pretty flakey, hovering some areas of the blue rocks with the mouse work - it logs the correct thininstance id - but more often it just doesn’t read the correct pixel values that correspond to the thininstance colorId.
You’ll also notice that I tried to generalize the method to work with different sets of thininstances (where each set corresponds to a different rootMesh). That code makes no difference on the net result right now since this is only being tested with one set.
Unless someone has solution that fixes both not setting the original color back, and always selecting the correct thininstance based on mouse position I’m going to look into other solutions that utilize the ammo js physics engine I’m working with.
The latest PG is less laggy on my laptop. I was able to open inspector this time. Your GPU frame time is quite high already: 18ms per frame. From my experience, I feel the texture resolution is too high in your scene. You have several 2048*2048 textures and the terrain is even 4096 * 4096.
Are you the one who wants to build a large open world? You probably need to use smaller terrain tiles. Make the tiles as instances as well. By doing this you can split the heightmap to multiple images with lower resolution, and apply these images to each terrain tile instances. For rocks in the scene, you can also use models with lower resolution texture images.
You have several 2048*2048 textures and the terrain is even 4096 * 4096.
Can you explain a little more what you mean by these numbers? When I open the inspector and scroll through the textures and materials properties, it isn’t immediately obvious to me what you mean by 2048^2 and 4096^2.
Are you the one who wants to build a large open world?
Yes, that is my goal. I’ll be looking into splitting the world into smaller content regions, that is the only way I’ll be able to get the physics working for each rock and tree that comprises the open world environment.
@slin I’m trying to use the approach of splitting up a large world map into smaller pieces, as you suggested, here:
I don’t get why the texture images for each mesh do not fit the mesh. Each mesh has: mesh.material.albedoTexture.uScale = 1 mesh.material.albedoTexture.vScale = 1
So shouldn’t that fit the entire image to each mesh exactly once?
Woah, sorry, that is so odd how I did not see that earlier. My bad.
It takes a minute or so for the scene to load on my machine. So if you don’t see anything for a bit, don’t worry, its just the massive normal map png being loaded (I haven’t split that one yet and all the original files are loaded first anyways).