Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Infinitown – A WebGL Experiment (littleworkshop.fr)
354 points by edejong on Nov 28, 2017 | hide | past | favorite | 104 comments


Here is a another infinite city written in a WebGL shader. https://www.shadertoy.com/view/XsBSRG

All the calculations are done on a per-pixel basis, there are no polygons or other objects created. The city is a 3d scalar field with effectively an isosurface plotted.

The city is made infinite with a simple modulo operation in X-Y on the field.

Interesting to note in this technique there is no additional computational load associated with more visible objects, and there can be as many objects as pixels.


That's pretty impressive, but it didn't work in FF (Developer 57.0b1 64-bit) for me, had to change to chrome and then it seemed to be getting 8fps (at least that's what the readout on that page was).

The Infinitown posted here was (pretty much) buttery smooth though, and relatively fast loading time (especially the second time with cache), and I bet the codebase is a lot easier on the eyes, though it's likely nowhere near as efficient as writing it all in the shader obviously.

Is the world just waiting for a no-dependency cross browser MMO/shooter/whatever 3D game to take the world by storm? Why worry about Steam when people can just go to a website, if the experience is good enough and the game is simple enough? I must not know enough about the industry/how hard it is to make a good game + how hard it is to make a truly good browser-only game.


While there might be something, modern games take a massive amount of data, and for a website, you'd have to load that before playing it. Plus it is difficult to monetize. Demos are fun and easy, full games take a lot of work. There are actually some cool web games already out there, but being in the browser isn't particularly interesting, in the end.

Infinitown is just a set of objects repeated in different orientations/combinations. The shader-city is awesome though. Very clever :)


If you're OK with handling a whole bucket of naivete, I'm going to really heap it on:

- the game monetization problem's always around (and always going to be around) -- is there a reason one wouldn't pay for a game in their browser but would pay for one on steam?

- Some of the greatest games of all time made do with so much less -- Isn't the resource problem just a matter of effort/ingenuity? Also isn't that problem bound to go away as time goes on? (though of course the "modern game" target will also move)

- I must not understand enough of why/how the demos are so different. Isn't shader city doing the exact same thing but insted drawing the visible pixels in space (and from a different viewpoint) rather than rendering the higher level polygons? I thought the key innovation/hard bit was the fact that it was inside a single shader.


Naivete is awesome when trying to not be it ;)

What does playing in the browser get you when you need to download 100MB+? You use the browser to get access to the standard features and DOM, if you ditch all that, add in a huge upfront download cost, then you might as well just install. There are plenty of cross-platform ways to do it these days. Additionally, browser games have an air (fair or not) about them of cheapness.

Then again, I'd be really happy if someone proved me wrong, and significant webgames became a thing. And it is a great exercise to analyze why webgames are bigger.

The infinite city is "just" tying a location to a randomly chosen and oriented set of objects. All the rest is standard scene graph rendering pipeline. The city shader does that for each "pixel" in the scene, and takes much less data to get a far cooler effect. Imagine coming up with an algorithm that picks a random lego object (a car, a police station, a boulder, etc) for each inch on your floor. That's infinicity. Now imagine picking a single lego piece based on your location and direction you are looking, and having that always match up even if you move, and when doing so, the resultant "legoscape" is a cool city. That's the city shader.

Sorta.


Being browser-based, you wouldn't be waiting to download 100MB+ if it's correctly designed

You'd download a 1-2mb core script bundle that then dynamically lazy-loads resources as required. For example, if Hearthstone were converted to a browser game, you would initially only load the base client, all the metadata and media (e.g. hero SFX, card data, effects, images) would be loaded on the fly as they are required, or pre-loaded at determined points (e.g. load all the data for both players' decks when beginning a match)


> I must not understand enough of why/how the demos are so different

The difference is that the shader city is a pure function of the inputs. For every value of 'time', it generates the colours for each pixel in the scene. Infinitown can maintain whatever state it likes in javascript.


you could associate data with the distance field based renderer - e.g. objects at x,y,z locations... the bigger problem imo is that working with such a fancy renderer is a headache. want to render anything else in there? you'll need to do custom depth writes or sort things... want to insert a custom building? now you have to cut a fancy hole in things .. etc...


Oh, definitely the infinicity approach is much more malleable, which is why game engines basically work that way after years of "evolution". But the shader approach is more impressive as a fun demo.

If you want to make a real game, you go with the infinicity approach!


As the shaders are basically only good for post-processing whatever output you get from your renderer, you'd definitely need to use an infinicity-esque approach for everything interactive in a game, but you could still leverage shaders in conjunction with that for non-interactive stuff like weather effects, animals (birds flying around etc), pedestrian and vehicle traffic and so on


I suppose you could use the technique to render a backdrop (either by rendering to a texture or by rendering it first, although you’d end up with a lot of overdraw if not careful) and then use a traditional renderer for the foreground. Not sure if it would win you anything, but certainly possible.

Could you also upload dynamic object data as VBO’s or uniform arrays or something and read that in your single-shader-renderer? Still likely not worthwhile, but a fun possibility perhaps.

I guess that’s not unlike what jheriko said above.


It's hard, much harder than creating a native client game. Many more access restrictions, javascript and flash were only two options in the past, and each had it problems.

I have been working on a browser based game for TOO long now, and garbage collection is a constant problem. Plus things just run a LOT slower than a native c++ client.


I'm really interested to know what the large problesm you've been facing are.

Also, if you're facing a problem with garbage collection, have you tried the emscripten/wasm approach? Using some garbage collected language and compiling it down to javascript? Or maybe even one that is functional to make garbage collection simpler?


Send me an email. Happy to talk to you about it. Just the garbage collection issues is enough to frustrate all but the most dedicated developers. I use pre-allocated object pools for just about everything that helps, but it's easy at 60 frames a second for one allocation to build up to thousands of objects quickly if you are not very careful.


I thought about it before. You could distribute your own builds prior to Steam. Here is a sample of the value Steam brings to developers: monetizing, managing DLCs, getting online features, getting visibility on the storefront, running promos/discounts/marketing operations, getting analytics, reviews, achievements, distributing free keys to testers, getting some partner connections to deploy server code, running a community forum, managing beta programs with two different builds, supporting screenshots, banning at the Steam level abusive players... it takes a lot of features to provide a meaningful MMO experience; the rendering engine sounds like 10% of the effort ;).


>That's pretty impressive, but it didn't work in FF (Developer 57.0b1 64-bit) for me

Could that be an issue with the new rendering engine? I'm on Waterfox 55.2.2, 64-bit, and it worked well for me.


It works great in Firefox 58.0b6 at a solid 60 FPS.


> All the calculations are done on a per-pixel basis.

Is there a term for this type of shader? Am I correct in assuming that this approach is primarily for demos, or is there a benefit to this approach for gaming or visualization?


Parallax mapping shaders do this kind of computation in actual games. In the case where the entire scene is rendered this way, you might see it referred to as a "two-triangle" shader like at [1] (since there's only two 'triangles' in the usual sense to draw the scene), but I doubt that this is at all common.

[1] http://www.iquilezles.org/www/material/nvscene2008/rwwtt.pdf


i've used this in practice for a number of full screen effects... e.g. if something is volumetric and you are inside of it, it makes more sense to draw two triangles than an elaborate mesh that completely bounds the player.


It's a pixel shader. It's widely used for everything involving 3D graphics these days, as most engines require you to implement one, even if it's a trivial one.


That example (and many on shadertoy.com) is called raymarching


Ive had it referred to as a full screen quad.


Little Workshop has done neat stuff, none of it rocket science, but all of it very polished. My favorite is http://www.playkeepout.com/

Sadly they never seem to open source anything? It'd be nice to see how such polished stuff is organized


Thanks, Keep Out is also my favorite project.

Our first web game, http://browserquest.mozilla.org, was actually open source: https://github.com/mozilla/Browserquest


I'm evaluating some WebVR options right now and wondering what you think is state of the art. Are things like a-frame and react-vr a step forward or a crutch? Is Unity viable for web-first apps?


Ah, I thought this was a side project of some Mozilla employees.


On mobile, that game runs better than any native game I've seen!


Oh man, Grimrock I miss you.


This is so cool! I'm always blown away by your projects Little Workshop. I recently finished building my first ray-tracer (https://github.com/diegomacario/Super-Sunshine). I felt proud of the images and animations I generated with it until I clicked this link - now I just feel like a caveman :p.


Have a look into implementing a glazed shader, it has some super nice results; it can give some surprisingly nice results for a very simple shading model https://imgur.com/a/TcliH .

There are more details on: http://www.cs.cornell.edu/courses/cs4620/2017sp/


That bunny is stunning! Thank you for the link, it looks like a great resource. Refraction, here I come!


I'm blown away by your README!


Thank you :-)! Writing it was by far the hardest part of the project.


That's pretty cool. Is there any way to rotate the camera? Also just saw a car and a truck crash into each other, but they both just drove off - next step maybe proper vehicle interactions and emergency services? :)


Thanks. Unfortunately, there's no way to rotate the camera (not because of technical limitations, but simply because it wasn't part of our vision).

There is some car detection code but it's far from perfect and collisions happen from time to time.


I was pleasantly surprised to see vehicles stopping for each other!


But they stop on the zebra crossings! No regard for pedestrians ;-)


They don't always stop realistically. Sometimes they stop exactly right before crashing into another vehicle.


me too, I wish people drove that calmly round here :)


Nice indeed. A few problems on my Firefox with shadows in the bottom left, and the question mark button does nothing.


using FF 58 on Debian, works flawlessly


You can tilt the camera by scrolling on your mouse.


Runs absolutely flawlessly on an iPhone 7. I’m not a game designer so no idea if that’s to be expected but to a casual it looks impressive running in a mobile browser.


Yeah I was really surprised how beautiful it is on my phone. Meanwhile my old i7 laptop barely gets 15fps...


Same for me on Chrome on Linux. I'm surprised I got anything on Linux since I didn't think Chrome devs bothered with webgl support on Linux.

Edit: Oh, this did the trick: https://askubuntu.com/questions/299345/how-to-enable-webgl-i...


That's weird, because my ages old i5 laptop renders it just fine. What browser are you using? Are you maybe in power saving mode? Odd.


It runs flawlessly on my cheap Nexus 5X. It's pretty low-poly, but I like the look.


Apparently, they are using three.js

The examples for this lib are also pretty cool:

https://threejs.org/examples/


I love making little demos with Three.js. It's amazing what a web browser can do these days.

The prettiest so far is https://fenwick.pizza/rentaduck


Quack!!!


Awesome! Makes me want to do 3d dev again. It even works runs really smoothly on my linux work-laptop(1).

(1) - After doing this: https://askubuntu.com/a/299346/81166


played around with threejs for fun http://3d.delavega.us what I realized is that this demo web app can probably run on over a billion devices: Windows, Mac, iOS, Android, Linux. try it.


Doesn't work without ajax.googleapis.com. Movements in this town are also tracked by Google.


We just wanted to improve loading speed by serving a Google-hosted version of jQuery (which is most likely already in users' browser cache).


And it tries to load data from googletagmanager.com

I wonder why. Isn't google tag manager a tool to "click together" modules for people who cannot write html?


> Isn't google tag manager a tool to "click together" modules for people who cannot write html?

or would rather not?


Unlike almost every other 3D WebGL (or Canvas) demo that gets posted on HN, smartphones were clearly given due consideration and hence this demo works beautifully in Chrome on my ageing Galaxy S6, including dragging around and using a zoom gesture to toggle viewpoint. Very impressed!


Pleasantly surprised to see this work smoothly on my iPhone 6s


Surprised it runs well on my linux laptop - except that here I can't click the ? which worked fine on my iPhone.


This is really neat, love how clean it looks. Any intention on a follow up post with a bit of behind the scenes information?


This is less of an infinite town, and more of a camera loop. You can see the houses end up being a simple repetition, and if you find a place that repeats a bit later, and you go very fast, you can see that the cars are also exactly the same (colors) in the same area. So it's definitely a loop.


Does anyone have any good advice on getting started building things in 3D using Unity and bringing it to the internet via ThreeJS? I've learned a little bit about threeJS but I'm not sure how to take things out of Unity and into ThreeJS and into my browser.


That's weird: I'm seeing a cloud bounce up and down as it slowly floats over the town.

Browser related? Here's my browser info for reference:

Build identifier: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0


It's actually an intentional animation. We just thought it looked cute. Interesting to know that it can be interpreted as a bug though.


Oh, I wasn't aware of that. Thanks for the clarification.

Yes, it did look like a bug to me because I didn't expect clouds to act like that in what I took to be a simulation of the real world.


Seems like it's animation related, meaning they intended it to animate like that.


Very nice demo! Safari really seems to struggle with this (2014 MacBook Pro, High Sierra). Chrome and Firefox show much better performance.


Just experienced the difference between Chrome and FireFox.

To be fair, I did have a lot of tabs open in chrome already. Like about 30.

Edit - 47 to be exact.


The cloud shadows look like they are in a different direction to the other shadows? Does anyone else see this?


Nice work!

I notice that the vehicles start and stop, whats the logic?

Is it doing collison testing?

Anyone seen any instances where it fails and vehicles collide?


Yeah they stop when another vehicle is crossing, but they don't seem to sync, so two vehicles sometimes resume driving at the same time and go through each other.


Yes, simple collison detection is available out of the box but I can imagine many "corner" cases that would fail and getting ghost vehicles passing through each other.


amazing performance and great visual style. i'd love to see it become a playable simcity-like.


Where'd you get the assets?


I don't know exactly where he got his assets (or if he made them himself), but this guy https://www.reddit.com/user/QuaterniusDev/submitted/ offers free assets in similar, colorful low-poly style



The about page says "Models by SimplePoly". So that's probably it.


Noticed a weird shadow on the heli landing pad. And lo, there's a cloud up there!


I find myself wanting to do something similar... thanks for the inspiration!


Stylistically this reminds me of Onett from Earthbound.


Wow, this town has good cell phone coverage :-)


They look like radio towers, not cell towers.


Wow this town has a lot of radio stations.


The cars sometimes drive through one another.


Very neat! I really like the visuals.


Doesnt work in Firefox Quantum


I had similar problems and a Refresh fixed it for me:

https://support.mozilla.org/en-US/kb/refresh-firefox-reset-a...

(note this will wipe out some settings)


It works for us. Which OS are you on? Also, any error message in the console? Thanks.


I'm running FirefoxDeveloperEdition 58.0b5 (64-bit) on MacOS.

Now, after a refresh it worked. But then again a refresh: grey screen. Refreshing with the screen open: It keeps working. But refreshing and then switching tabs quickly, and switching back: grey screen. (however very difficult to reproduce)

Logs only show this: unreachable code after return statement [Learn More]


It surely works on Windows.


Is it a Unity app exported to HTML5 (w JS and WebGL)?


Hi, no we only use Unity to assemble individual city blocks and export the data with a custom Unity script. It doesn't use the official Unity WebGL exporter.


> Made with: Three.js, Blender, Unity.

Seems so.


It is very strange. It seems to have a lot of Unity shader code in it. Much of it verbatim from Unity's source code.

But the rest of it is Three.JS. Thus were the assets created in Unity and someone copied the shader code to ensure that they render the same in ThreeJS as in Unity? I am a little confused.


Hi, I'm one of the developers. We use Unity as our main scene editor and exporter. We don't use the official WebGL exporter but a custom script that we wrote. In this project, we use it to assemble individual city blocks, that we merge to a single geometry each. We actually don't use Unity shaders at all, they are also custom made.


Thanks for the explanation. That makes sense. Neat stuff.

Btw there is proprietary/coprighted unity shader code cut and pasted into this, someobe even copied the original comments from the unity shaders. For example search for "DecodeLightmapRGBM" in the below source code, which is from the demo - that code and others are copied:

https://gist.github.com/bhouston/1c3c6835ca9766571f07ad0126d...

Here is some unity source code to compare against: https://gist.github.com/nicloay/8d2ae254a77de58bb42b9009b4cf...


Thanks, good catch. That is a copy&paste that I mistakenly left in, it wasn't used anyway. I removed it now.


Just curious, why do you do it that way? (i.e. not just exporting from Unity)


Don't know about this specific usecase, but Unity exports are heavy. I mean, it compiles C# scripts to C++ and then compiles it and Unity C++ runtime to Javascript. I easily got download sizes in tens of megabytes when trying to use Unity export for simple demos. Meanwhile Three.js is very lightweight and more than enough for such projects.


Because the Unity WebGL exporter doesn't currently support mobile.


Lovely work.


Cool, but a bit uncanny just how realistic it is. Makes me uncomfortable not to know if I'm looking at a simulation or actually flying over a city, as if in an airplane.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: