5 ms·
Nice! Some feedback from a Three.JS contributor: - I notice you are using Collada 3D model files inside of a zip file: https://play.freeciv.org/3d-models/mode
by bhouston 10y ago
Nice! Some feedback from a Three.JS contributor:
- I notice you are using Collada 3D model files inside of a zip file: https://play.freeciv.org/3d-models/models.zip https://play.freeciv.org/3d-models/models.zip It may be better to store the models in glTF format. It would be smaller and faster loading. Although to be honest, the last time I checked converting to glTF with high fidelity was very difficult to do.
- You should probably have cache forever on your game assets (3d models, textures, etc.) but have version numbers or hashes (my preference) associated with them -- it will load faster.
- Even if you do not switch to glTF, it might be better to have each Collada 3D model as a separate resource, so that as you change things it doesn't have to redownload the whole zip file.
- It is weird that you have *.zip file. You can likely just serve the collada assets using the built-in HTTP gzip encoding: https://en.wikipedia.org/wiki/HTTP_compression https://en.wikipedia.org/wiki/HTTP_compression Thus it will be handled by a faster path in the browser than using a JS unzipper.
- You may want a proxy scene of boxes to raycast against. Hit testing my simple scene takes 5ms and I have a top end computer. Ray casting against THREE.BufferGeometry in Three.JS is just unreasonably slow. And THREE.Geometry is just slow all around, even though raycasting is a bit faster than with THREE.BufferGeometry. Another approach is to render the scene a second time to the offscreen with unique colors per object. Then hit testing is just figuring out which color was at the pixel under the cursor. This is highly scalable and is a very commonly used technique in games.
- roschdal 10y agoThanks for the feedback! I'll try using the glTF format. I'm putting the Collada files in a zip file to save CPU resources on the server, since compression on the HTTP layer would use more server CPU. Also compressing all the models in a single zip file results in overall less bandwith usage, and bandwidth is limited on our server. Do you have more ideas about improvements?
- fulafel 10y agoYou can use pre-gzipped static files.
- bhouston 10y agoDetails on how to do this with nginx: http://serverfault.com/questions/241347/how-do-i-server-pre-gzipped-files-with-nginx-so-that-theyll-be-shown-as-text-in http://serverfault.com/questions/241347/how-do-i-server-pre-...
- roschdal 10y agoI have tried. The total bandwidth usage was less when using a single zip file, probably because of similarities in each of the collada model files.
- bhouston 10y agoCollada is an XML-based format -- it is just brutally bad. You need to use a binary format for fast loading times. Thus binary glTF or binary Three.JS or something custom.
- corysama 10y agoJust pounding this in even further because I see it so much: Collada, OBJ, STL and similar formats are expressly designed to be editor formats and expressly not intended as consumer distribution formats. Any time they are used they give the app and WebGL in general a reputation for being bloated and slow. You wouldn't use PSDs in your webpage. You'd use PNG/JPG. Pleas don't use Collada in your web page. Please use glTF.
- mook 10y agoSince the models are static content anyway, perhaps try a CDN. Since you're already using GitHub, perhaps https://rawgit.com/ https://rawgit.com/ would be useful (mostly because it's free) until you decide you want something with guaranteed uptime.
- willvarfar 10y agoI serve my Ludum Dare games from gh-pages. Works great.
- bhouston 10y ago- You could also use Three.JS's binary format. It isn't half bad, especially served using HTTP compression. Blender can do conversions to it pretty well. - You can use Canvas to draw to and then convert those to textures, that can make it easy to create very interesting pop-up information in the 3D scene. You could have the Canvas cleared to transparent and then write non-transparent stuff to it. Then you will have text and graphics floating in the air. Could look cool. - You could use a DOF pass so that the 3D world could look tilt-shifted: https://en.wikipedia.org/wiki/Tilt%E2%80%93shift_photography https://en.wikipedia.org/wiki/Tilt%E2%80%93shift_photography https://threejs.org/examples/webgl_postprocessing_dof2.html https://threejs.org/examples/webgl_postprocessing_dof2.html - You could use a Bloom pass with HDR to get some nice shines: https://threejs.org/examples/webgl_postprocessing_unreal_bloom.html https://threejs.org/examples/webgl_postprocessing_unreal_blo... - You should probably try to use the STandard material model (GGX + Metallic + Roughness) in Three.JS rather than Phong. Looks much better: https://threejs.org/examples/#webgl_materials_standard https://threejs.org/examples/#webgl_materials_standard - Use the static serving of gzipped assets as discussed elsewhere. - You should have hashes on your *.js files with caching for ever. This is pretty standard practice. - Think about using the HDR stuff I contributing to Three.JS -- it can lead to amazing looking materials. Here is an example that uses IBL and HDR and tonemapping: https://threejs.org/examples/webgl_materials_envmaps_hdr.html https://threejs.org/examples/webgl_materials_envmaps_hdr.htm... https://threejs.org/examples/webgl_tonemapping.html https://threejs.org/examples/webgl_tonemapping.html Given that you are in daylight, I think this would work amazingly. Would look way better than simple lights. But it only works on Standard/Physical materials and not Phong materials. I didn't look into too much more as I only looked at the production minified code.
- roschdal 10y agoThanks! Very useful.
- deleted 10y ago[deleted]
- foota 10y agoNot sure you're still following or not, but could you design a "folder" format that is then gzip encoded? Then you get the best of both worlds.
- thegeomaster 10y agoTo address your last bit about raycasting: Rendering a scene to another buffer is a good way, although you do need some minor tricks to get information such as position and normal of the intersection, particularly so with high precision. It's worth noting that this approach causes a very costly GPU/CPU sync when hit testing needs to be done and the scene has changed since last time (because glReadPixels() has to be called to pull in the data from VRAM to RAM). This is wasteful if the scene changes every frame, as you're essentially limiting the performance of your GPU to the performance of your CPU. Rendering to a smaller off-screen buffer (thus sacrificing precision) or calling glReadPixels() at most on each Nth frame and relying on temporal coherence to save you from the most unpleasant false positives and false negatives.
- bhouston 10y agoI've had good success, but you can often only read back a single pixel, rather than everything. I haven't profiled it recently. I understand that it can be fairly fast these days with PCIe buses.