Is there a way to render certain objects in a scene at lower pixel densities?

My game involves a baseball stadium. I recently was able to add about 16,000 fans and seats into the stadium in a decently optimized way. I’d like to be able to render those at a lower resolution than the other objects in the scene. Any way to accomplish this with ThreeJS? Custom shader maybe?

you would typically do that with LOD, three has a class for it. three.js docs this allows you to display objects with fewer vertices and lower res textures in the distance.

here’s a small example https://codesandbox.io/p/sandbox/re-using-geometry-and-level-of-detail-12nmp

if you don’t plan to move the camera near any of those fans in the stadium then just lower vertices/texture res, you would not need anything for this, just blender and an image editor or squoosh. btw i hope the 16.000 fans are instanced into a single draw call, otherwise that’s the bottleneck that should be fixed.

you would typically do that with LOD, three has a class for it. three.js docs this allows you to display objects with fewer vertices and lower res textures in the distance.

Yeah, but there’s a problem with that in my situation. I create all the crowd meshes by translating geometry, then combining them. I haven’t thought of any other effective way to do it right now, so my crowd mesh containing 16,000 fans and seats, which is broken into about 36 separate meshes and all technically have a position of 0, 0, 0… and the LOD system needs a position of the mesh, so…

if you don’t plan to move the camera near any of those fans in the stadium then just lower vertices/texture res, you would not need anything for this, just blender and an image editor or squoosh. btw i hope the 16.000 fans are instanced into a single draw call, otherwise that’s the bottleneck that should be fixed.

The camera is always movin. The fans are combined into geometries in an optimized way.

lower the vertices and texture resolutions in that case. three just renders at the dpr you set on webglrenderer, it’s a global setting but textures/vertices are under your control. you can get away with removing vertices until the model shape is but an absurd blob, but the textures make that hard to spot.

Might be a good use case for InstancedMesh. Like if you have 16,000 seats total, allocate one InstancedMesh with low-quality versions of up to 16,000 seats, and allocate another InstancedMesh with up to ~250 higher-quality seats, then periodically (not every frame!) reorder the instance transform matrices so that the closest 250 chairs are omitted from the low-res mesh and included in the high-res mesh. Note that InstancedMesh should be allocated with the most instances you’ll ever draw, you can always reduce the count you actually draw after allocation.

Ideally the mesh simplification happens offline but if you need to do it on the fly, see:

2 Likes

lower the vertices and texture resolutions in that case.

They’re currently cube people. They’re just 8 verts with the bottom face missing for a slight optimization. I’m only askin about per object pixel density because I know if I add more detailed fans, something would have to be implemented, whether LOD, pixel density, or both.

It doesn’t run badly right now. It stays at 60 FPS, but like I said, I’d like to make the crowd more detailed and I know it’ll need some kind of distance-based optimization.

Take a look. I even added movement to the verts to give more life to the crowd…

Thanks, this may work for me. I’m gonna look into it further when I get a chance…