
WebGL Terrain Flyover Demo - lukes386
http://www.zephyrosanemos.com/
======
sramsay
"When I tried to think of a project suitable for learning JavaScript, a
terrain flyover demo came to mind."

Me too! But then I re-establish contact with the reality of my actual
abilities and create a button which, when pressed, prints "Hello, world!" to
an alert window.

~~~
nestoras
Haha thanks :) I've done these things in the past many times, only on
different platforms. The real kudos go to the browser guys (especially at
Mozilla and Google) for all the superb work they've done on WebGL and
JavaScript in general. Learning JavaScript and some of the intricacies of
developing for the web has never been more fun! :)

~~~
Tloewald
Not discussion that I can see of your rendering techniques. Are your shadows
baked?

~~~
nestoras
Yes, they are generated offline. It's the most time consuming step when
generating the terrain.

Doing the lighting and shadow generation in real-time (during tile
initialization) is a very interesting problem! The great advantage is the
bandwidth reduction and the ability to move the sun of course. A Web Worker
can (probably should) be used for that purpose. The problem is that in order
to correctly light a tile, you need access to its adjacent tiles as well
(since peaks near the border on their side may be casting shadows on our
tile).

All in all, very interesting and certainly doable!

------
networked
Cool demo. What caught my attention was this line in the description:

>The terrain is procedural, generated offline by a Delphi program (Delphi is a
modern version of Pascal).

Nowadays I very rarely see new projects use Object Pascal or Delphi. This is
somewhat disappointing since I think it really is a fine language that could
be a viable alternative to C++ and Java due to its combination of high
performance and clean syntax [1]. But then again, C# is _very_ popular and it
is pretty much the new Delphi.

Does anyone here use Object Pascal in their current projects?

[1] At least in theory. I'm not necessarily talking about the particulars of
the Borland/CodeGear/Embarcadero implementation since Anders Hejlsberg left
for Microsoft, which were not always perfect.

~~~
jevinskie
I was very impressed when I found out that Pascal supports subrange types
(that is types with custom, user-defined ranges). I had only seen it in VHDL /
Ada before, where I found it to be very useful.

~~~
nestoras
Yes, that has been a feature of the original Pascal design, since the 1970s.
Very useful for catching out of range errors.

------
lalc
This looks great and that is a huge amount of effort. I have to ask about what
I think is the elephant in the room: Surely you must have noticed that all
your mountains are chopped off at the exact same altitude? Wouldn't the scene
look way better if you just increased the maximum, with basically no effort?

It's as though you spent a month painstakingly mixing 64 channels of crystal
clear audio, but, right at the end, threw your hands up and clipped the final
mix into oblivion.

~~~
nestoras
Very good question! Actually, I can't increase the maximum without going to
two bytes per elevation. All of the (top) plateaus are at a height equivalent
to 255.

Q: OK, why not put them a bit lower than that, with some variety between
peaks?

A: I already have. If you take a closer look, you will notice that there is
another layer of flat surfaces, lower than the top.

Q: I'm not convinced. Why only two layers of 'flatness', one at the top,
another a bit lower?

A: In the end, it's all about the dynamic range that you have to work with.
When using a single byte, there are only 255 distinct height values. The key
point is to understand that these values must not differ by much (i.e. they
cannot be scaled by large values), since this will affect the appearance of
the rest of the terrain (think very, very sharp, unnatural triangles
everywhere). On the other hand, the scale factor must be large enough to allow
for distinct terrain 'features', avoiding the appearance of a deflated
terrain. Two layers of flatness, safely away from each other, was the best
compromise.

Q: I'm still not convinced. Just vary the top layer by a small amount between
peaks.

A: Using a small value wouldn't make much of a difference. If the amount was
large enough, the distinction between the two 'flatness' layers would be lost
and the terrain would lose that specific character that it currently has.

Going to two bytes per elevation (and thus be able to use a small scale
factor) would allow me to keep the style intact (of some specific geological
procedure that has formed the terrain), while varying the peaks and keep the
rest of the terrain smooth.

I hope this made some sense. However you're right, it is noticeable! I just
didn't think it detracts that much from the overall feel, while it still has
advantages, so I went with it.

~~~
pfraze
Could you add a cheap procedural function in the rendering pipeline to get
more depth variety (past the 255 limit)? You might avoid adding the byte that
way, though I'd guess it depends on how much of the pipeline is locked into
that limit.

------
sxp
FYI, directly working with WebGL code is painful just because of the amount of
basic infrastructure that has to be built before anything can be done. I
strongly suggest using an existing framework like three.js as a starting point
and going from there. Three.js is complete enough that a basic scene can be
created quickly and extensible enough that complex scenes and shading can be
created by extending it with custom objects.

For example, I was working on creating a WebGL setup for playing around with
the Oculus Rift and used three.js to create <http://sxp.me/rift/>. It's mostly
three.js code, but I added a custom camera object which handles the offscreen
rendering and distortion required for the Rift. It was much faster and easier
than starting from scratch which was what I originally did before giving up.

~~~
nestoras
I agree! Three.js is excellent and already a de facto standard for developing
in 3D. However, some points:

1\. As the demo stands, it doesn't really need a 3D engine. Including one (any
one) wouldn't help with anything, except for maybe skipping some (miniscule)
setup code. Surprising, but true. Things definitely change as soon as you wish
to render a flying ship though.

2\. Learning has been the main reason for this demo. There's no better way to
learn than to take apart or build something from scratch. In fact, I've built
a 3D engine as well during this time (not used in this demo at all), along
with a 3D model viewer and an application I hope to turn into a start-up some
day. If I've been developing a 3D game (for example), with the express purpose
of releasing it as soon as possible, I'd certainly use Three.js!

And last but not least:

3\. When I decided to get into web development, about one and a half years
ago, I didn't know about Three.js! :) (I found out quite soon though)

------
mcmire
That looks really nice. A lot of WebGL demos these days don't really show the
full extend of what WebGL can do, so to my eyes it's basically equivalent to
something like VRML (anyone remember that?). Of course WebGL/OpenGL and VRML
are totally different but you get the idea. Yeah I know there's stuff like
Quake in WebGL but it's not really the same thing, because Quake was designed
for lesser powered machines.

I'm still waiting for someone to make a fully fledged game in WebGL because I
can totally see it happening.

------
Aurel1us
Now add the ability to drive with a motocross through the landscape :)

Very impressive!

~~~
nestoras
Thank you. In fact, I may add a ship flying and shooting missiles, as soon as
I get some free time. This will require the implementation of a shadow
algorithm (you'll need a way to gauge the ship's height) and a particle system
(for the smoke trails and explosions). Already done that in an old desktop
implementation I've kept somewhere.

A motocross would be slightly more difficult :)

------
bjourne
Looks nice but runs at awfully slow 4-5 fps on my Ubuntu 64bit system. Is
Radeon HD 4200 to weak for WebGL or is there something you need to configure?

~~~
nestoras
I think it's an issue with hardware acceleration on Linux :(

~~~
hideo
JustFYI, I'm getting an excellent 40fps-70fps. Thinkpad E420 (intel GPU)
running 64bit Linux Mint 14

$ uname -a Linux XX 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC
2012 x86_64 x86_64 x86_64 GNU/Linux

~~~
luos
Did you install specific drivers for it? I'm using a Thinkpad T420 with
xubuntu and i only got 12-13 fps in Chrome 24.0.1312.52.

edit: Ok, I figured it out, it's because I used an external 1920*y display, if
I resize the window it gets faster.

------
daenz
Very cool. Are you using occlusion queries for the lens flare sprite? This
something I implemented recently in my engine. Eventually I want to do
something like this... [http://john-chapman-
graphics.blogspot.com/2013/02/pseudo-len...](http://john-chapman-
graphics.blogspot.com/2013/02/pseudo-lens-flare.html)

~~~
nestoras
Thank you! I didn't have time to implement image-space occlusion queries, plus
I wasn't sure of the level of support they have on mobile hardware (not that
this demo will run on anything mobile for the time being :)). I'm shooting a
grid of rays through the terrain instead (see relevant screenshots), using
various techniques to accelerate that.

The result is used for modulating the intensity of both the lens flares layer
and the glare layer.

Nice article!

~~~
gisenberg
FWIW, this demo runs on Chrome Beta for Android with WebGL enabled (although
the UI is a bit unusable in that context).

------
grannyg00se
Outstanding work. I noticed that resizing my browser window actually changes
my view portal size. I expected it to keep the same portal resolution but
shrink/stretch/distort the view as I resized the browser. I'm not sure what
the implications are, but it was a fun surprise. I also noticed that the
framerate scales very nicely with the changing portal view resolution as I
resize the browser. Very impressive.

~~~
nestoras
That was the behavior in the early development stages. I wanted to include
both behaviors for educational purposes (it is very instructive to be able to
observe what happens when you change the rendering window and how the frustum
adapts - or not).

The scaling in frame rate has to do with the amount of terrain patches that
have to be displayed. You can see the same scaling by changing the frustum
viewing angle (i.e. without resizing the browser window).

Thank you! :)

------
angersock
Out of curiosity, do you use dynamic index buffers to accomplish the
geomipmapping, or do you just trample the vertex buffers every frame?

~~~
nestoras
There is only one vertex buffer per patch that contains all of the vertices.
Index buffers are being used, all of them pre-generated of course and uploaded
to the graphics card. Rendering a patch then becomes a simple matter of
selecting the right index buffer (or index buffers, since stitching requires
more than one drawing call).

~~~
angersock
Ah, nice!

------
shanelja
I don't even have words for how cool this is, it really shows how far these
web technologies have come from their humble beginnings.

~~~
nestoras
Thank you :) The technology has matured to such an extent that I think we'll
see many great things in the immediate future.

------
kurd_debuggr
Absolutely fascinating write-up, and the demo is very nice. A quick question
of if the code closed-source?

~~~
nestoras
Thank you :) I'm glad that you liked the write-up as well. Yes, I've received
many requests for the source code. I'll clean it up and make it public as soon
as I find some time.

------
th0ma5
Surprising I got 0.1fps on a Dell Mini 9 with Ubuntu. I'm used to these things
either not detecting WebGL or just crashing the tab.

------
pyalot2
That's cool stuff :) (believe me, I know <http://codeflow.org/>)

~~~
nestoras
Thank you! I'm the guy who made it. It's very nice hearing these words from
you. I remember checking out your blog many times in the past :)

~~~
pyalot2
Woah, I just realized that you draw the entire GUI by yourself.

Don't get me wrong, that's pretty awesome in itself, I've done things like
that myself. But I'd like to suggest (or perhaps inquire) why you wouldn't
just overlay some html?

~~~
nestoras
When I started development, I didn't know that DOM controls could overlap, let
alone lay over a WebGL canvas :) I had zero HTML (and general web development)
knowledge at the time. Since I have some experience doing this kind of stuff,
instead of diving into the scary DOM details, I took the path of least
resistance for me (begun implementing a GUI on a nice, clean drawing surface).

Joking aside, it didn't start as a fully-fledged UI. Some scrolling text
strings to show a message log first, the ability to move them out of the way
later, then implementing a proper window container for them, then introducing
the concept of a 'widget', then getting really excited and thinking about a
layout system to be able to present multiple widgets per window... that's the
way it usually goes :) The GUI turned out a lot more demanding than the
terrain engine itself, both in development time as well as rendering load.

In the end, it's all about learning!

------
jakejake
Every time I click on a WebGL demo I think to myself... here comes my CPU fan
and my lap is about to get hot! Seriously though, this demo makes me realize
how much programming knowledge I lack. It it totally fascinating. Where would
be a good place to start learning this type of programming?

~~~
nestoras
Thank you! I know what you mean about the fan :)

For learning, you can try game development sites, graphics programming books,
online Geomipmapping tutorials (for terrain stuff), forum discussions when
facing problems... However, the most important thing is general programming
experience, I guess.

I remember though that Learning WebGL (<http://learningwebgl.com/blog/>) was
very useful when I began learning things specifically for the web!

~~~
jakejake
Cool thanks so much!

------
shurcooL
That's very cool. Nicely polished, that's a lot of hard work and effort.
Congrats!

I can relate to your story of building the UI framework yourself. That's kinda
what I ended up doing myself too, and I've learned a lot of fundamentals
through that approach.

~~~
nestoras
Thank you. You're right, that's how learning is done :)

------
cousin_it
Let me take this opportunity to plug a 3D terrain I made in Flash about three
years ago: <http://kosmosnimki.ru/3d>. It uses actual satellite images and
heightmaps.

------
satori99
Impressive!

Is there a reason you decided to implement a WebGL UI, instead of using HTML
for the user interface elements?

Is native browser compositing too slow with multiple HTML elements on top of
the WebGL canvas?

------
ntaylor
Incredibly impressive. I, like you, began my first endeavor into learning JS
by building a GUI. Unlike you, my resulting product was ugly as sin. This is
seriously awesome work.

~~~
nestoras
Thank you! Building a GUI is quite challenging and very interesting as well :)

------
webwielder
So happy to see Planet Morphiter alive and well:
<http://www.youtube.com/watch?v=uAHBOtOgz0Q>

------
rodrigoavie
Wow. Awesome work. I will try applying some of my little Linear Algebra and
see how I can mix it with Computer Graphics and WebGL, more specifically.

------
HunterV
Simply delightful. I spent a good amount of time flying through the terrain
attempting to avoid the mountains. Thank you!

~~~
nestoras
You can accelerate by pressing the down arrow key and even overwhelm the tile
prefetcher by pressing the 'O' key and accelerating even further (this is not
a very publicized fact due to bandwidth concerns :)).

Thanks for the kind words!

------
adamnemecek
Amazing. How long did this project take you?

~~~
nestoras
Thank you!

Can't say for sure, because I didn't make it all in one go. The first time I
opened the browser with the intent of developing for the web was a year and a
half ago. During that time, I've built some other things as well (a 3D
graphics engine, a CAD-like 3D model viewer to test the engine with and an
application I'd like to turn into a start-up someday :)).

If I had to guess, I'd say that the terrain took me 3 to 4 months, the GUI a
bit more than that, plus two more for really polishing the demo. Hard to say
though, since everything was done in parallel, with even a few dead periods
in-between.

------
LolWolf
That's... just beautiful. Congrats, great job; saving it for my reading list.

------
pfraze
this looks really good! Is the source available?

~~~
nestoras
Thank you :) I'll clean it up a bit and make it public soon!

~~~
msprague
Please do! I'd love to see it!

------
CamperBob2
Really beautiful work, Stavros.

~~~
nestoras
Thanks CamperBob2! :)

------
jfolkins
Seriously impressed.

~~~
nestoras
Thanks :) I had a lot of fun making it!

------
funvit
amazing work!

~~~
nestoras
Thank you :)

------
antoniuschan99
really cool demo Stavros!

~~~
nestoras
Thank you! I wish I've been more thorough when I was developing everything and
keep a journal. The progression is very interesting. I do have older versions
though, I may use them to illustrate some points in future blog posts (when I
figure out how to setup a blog :)).

------
juskrey
mars.exe, I miss you

------
chii
very impressive!

------
drivebyacct2
Chrome Beta for Android gets 3fps. Firefox Beta for Android crashes. Just FYI.

edit: 60.1 FPS at 2560x1440 on my desktop (KDE/KWin/Chrome Dev)

~~~
nestoras
Thank you! Quite frankly, I'm surprised the demo even runs (I don't have a
smartphone currently). On what device did you test it?

~~~
modeless
10 FPS on my Nexus 4 with Chrome Beta. 20 FPS without the GUI. Very nice!

------
johncoltrane
Cool. I love minimalism. That black background and that simple and polite
sentence in white font looks good and loads fast!

