Infinite tunnel with ceiling SpotLights

This is a new version of an old demo of mine:
https://eliashasle.github.io/tunnel.html (will take a few seconds to load)

Very much inspired by this tunnel in my neighborhood, and following Norwegian standard dimensions on the road markings.

Control with arrow keys, or optionally with anything gamepad-like. It has been a long time since I tested with anything else than arrow keys, and it was only ever tested on one set of steering wheel and pedals, so I can’t promise anything.

The fog is exponential. See https://github.com/mrdoob/three.js/pull/17355

I will appreciate feedback on how smoothly the demo runs, and on how it responds to different gamepads. I have not yet done any tricks like merging geometries, so the number of draw calls is substantial (192 per frame, the last time I checked).

I have plans for the future of the “game”, but must make sure to postpone them until I really have the time.

1 Like

I confirm that it is heavy on my GTX 770. It runs smooth but the GPU is already at its maximum. Once you add more details, it might lag: for example, in this type of scene you could add post-prod glowing effect and that would burn my GPU… Have you created lightmaps to fake the lights? The scene is very demanding even if the car is not moving.

Otherwise, controls are good and the overall sensation is nicely simulated!

Thanks a lot for the feedback!

in this type of scene you could add post-prod glowing effect and that would burn my GPU

Hmm, I have never tried three.js post-processing, but a glow effect sounds tempting… :wink:

Have you created lightmaps to fake the lights?

No. Everything is live, but don’t worry. There is not really an infinite number of lights. Only 40 or so. :angel: I don’t know exactly how to make a lightmap either, but I know I could have used the same one for each tunnel segment, due to the infinite repeating pattern. But lightmaps cannot represent the specular component, right? So I would have to fake that separately (it is not very pronounced on the effects of the ceiling lights, though). And once I add other cars/objects to the scene, I will also have to fake shadows? It would actually not be that hard, I think. maybe I could blend two shadow meshes, one pointing from each of the two nearest ceiling lights. Using a smoothstep (cubic Hermitian spline) blend.

I think the easiest improvement I can make is to merge all static objects with same material into a single geometry. That way I will reduce the number of draw calls per frame from 236 to 7 or so.

Otherwise, controls are good and the overall sensation is nicely simulated!

That’s good to hear! :smiley:

I tried it on my Macbook Pro 2018 (AMD Radeon Pro 560). Maxes out the GPU, but runs pretty smooth at 60 FPS.

Pretty nice demo. Why does it take so long to load up initially?

EDIT: tried it on my Chromebook (Intel HD Graphics) and it runs at 10 FPS

I am restructuring it, but struggling to get everything to work. I think eventually it will run really very much faster.

Why does it take so long to load up initially?

I am not sure, but I do create some textures at startup.

New version. Reduced renderer.info from

  1. memory: {geometries: 8, textures: 4}
  2. programs: 4
  3. render: {calls: 236, triangles: 1612, points: 0, lines: 0}

to

  1. memory: {geometries: 6, textures: 4}
  2. programs: 4
  3. render: {calls: 9, triangles: 1248, points: 0, lines: 0}

@Droopie Does it run smoothly now? Still slow startup, I guess.

40 moving spotlights sounds a lot to me… In the PBR pipeline, lightmaps/shadow maps are just a B/W map and have not influence on Roughness maps (specular-like map). They are a lot cheaper than lights: DOOM was made of maps/textures. In Blender “lightmaps” are called “shadow maps”, I’ve always considered them to be the same.

Also, even with textures, you’ll want to have only 40 segments… just to make sure your scene is as light as possible before adding details, like cars, animations, logic, network, sound,…

I am not sure what shadowMesh works… I wouldn’t know how to merge the shadow of a moving character with the shadow of the environment. I think it is possible as they both are B/W maps.

They are not moving, but indeed movable. And moving in view space.

I haven’t really considered lightmaps yet. I don’t even know yet if they are applied with UV mapping (emissive map) or with projection (like the shadow maps in three.js).

I am not sure what shadowMesh works… I wouldn’t know how to merge the shadow of a moving character with the shadow of the environment. I think it is possible as they both are B/W maps.

The point would be to get rid of all the static SpotLight objects and fake all the effects. Using lightmaps on the geometry and either a custom shadow map projection or some other shadowing method, like shadow mesh (in either case only considering the two nearest lights for each shadow-casting mesh).

Well lowering the draw call from 200+ to 9 has had a significant improvement for my GPU. I was a bit worried when it hit the 100% mark with just graphics. Now it’s at 40%. Much better!

1 Like

Thank you for testing again! I have noticed some occasional “jaggering” with the new version that I believe was absent in the older version, though. Hm.

I think another possible solution than lightmaps could be to go back to tunnel segments and use instancing, where only a few spotlights are considered for each instance, and only their relative positions to the base geometry and the camera are considered. This way I can achieve exactly the same result as using 40+ full spotlights.

For some reason it dropped down to 53 FPS on Macbook and to 5 FPS on my Chromebook

That is disappointing. Maybe the approach I outlined above will work better. If Intel HD supports instancing etc.