
WebGL Water - morphics
http://madebyevan.com/webgl-water/
======
double051
Some people are mentioning that this doesn't work on iOS, and that's because
Apple doesn't have WebGL available in mobile versions of Safari.

But it is. This post by Nathan de Vries [0] shows how you can hack the
UIWebView to enable WebGL contexts in your iOS apps. You have to get a little
more creative these days (the compiler has gotten stricter about private types
and functions), but all it takes is something like this:

    
    
        -(void)setWebGLEnabled:(BOOL)enableWebGL forWebView:(UIWebView *)uiWebView
        {
            id webDocumentView = [uiWebView performSelector:@selector(_browserView)];
            id backingWebView = [webDocumentView performSelector:@selector(webView)];
            [backingWebView performSelector:@selector(_setWebGLEnabled:)
                                 withObject:[NSNumber numberWithBool:enableWebGL]];
        }
    

It should go without saying that code like this will not make it into the app
store.

[0] [http://atnan.com/blog/2011/11/03/enabling-and-using-webgl-
on...](http://atnan.com/blog/2011/11/03/enabling-and-using-webgl-on-ios)

~~~
q3k
Why the hell would Apple disable WebGL by default, if they went through the
trouble of somehow getting it working in the first place..? Incredible.

~~~
sirkneeland
2 possible reasons:

1\. so they could be prepared to rapidly enable it if market exigencies
required them to (say, if webGL experiences for whatever reason started
blowing up on competitor platforms).

2\. they have some other, grander plan behind webGL that we don't know about
yet. Maybe someday they want Xcode to be the premier web app dev tool

Remember this is from the company that developed Mac OS X in parallel for
PowerPC and x86 "just in case"...clearly they plan for the future

~~~
foldor
They didn't develop them in parallel. One programmer took it upon himself
alone, and without telling Apple, to do the initial port to x86.[1]

[1] Insider cuts into Apple, peels off Intel Mac OS X port secrets -
[http://www.theregister.co.uk/2012/06/11/apple_project_markla...](http://www.theregister.co.uk/2012/06/11/apple_project_marklar_secrets/)

~~~
sirkneeland
Interesting background stuff! I didn't know, thanks for sharing.

------
frik
It would be great if Apple would activate WebGL on iOS!

    
    
      Officially only available through iAd on iOS 4.2 and higher, for all devices 
      except for 2nd Gen iPod Touch or iPhone 3G and earlier. However, there is a tweak 
      for jailbroken devices to enable functionality for Mobile Safari and all other 
      WebKit browsers.
    

[http://en.wikipedia.org/wiki/WebGL](http://en.wikipedia.org/wiki/WebGL)

Today, even Microsoft supports WebGL with IE 11, so hopefully Apple activates
it with iOS8...

~~~
ANTSANTS
I dunno, I'm not really crazy about the prospect of random web sites murdering
my phone's battery with superfluous WebGL animations. Remind me again why web
pages need the ability to display realtime 3D graphics?

I don't like a lot of what Apple does, but I'm glad _somebody_ isn't thrilled
with the idea of "the browser" becoming the world's most Lovecraftian cross-
platform runtime, even if it's only out of self-interest.

~~~
CamperBob2
_Remind me again why web pages need the ability to display realtime 3D
graphics?_

The answer is the same one that would have been given to people in 1991 who
were asking why Gopher wasn't good enough.

~~~
ANTSANTS
Cute comparison, but it's not really fair. The web was quite obviously more
useful than Gopher, while WebGL offers no improvements to the web for its most
important tasks of being the standard tool for communication and the interface
to most of humanity's services. Somehow the web managed to be "good enough"
for those purposes for 20+ years without WebGL.

I think a better comparison is to the Java applets of the late 90s and early
2000s: Cool demos, cool games, totally pointless and enormous security
vulnerability. But hey, the Runescape devs made a lot of money off of their
Java-applet MMO back in the day, and someone will probably do the same soon
with WebGL, and _that 's what the web's all about._

~~~
bpafree
Webgl is very important to the development of data visualization, educational
and scientific simulations and explorable explanations. There's a lot of room
for interesting applications in this space. See redblob games for an example
of what I mean specific to teaching game algorithms.

------
constexpr
Author here. I've done much more awesome stuff with WebGL since I made this
demo but it's for my startup and is not public yet. We're actually looking for
a backend engineer with graphics experience at the moment. Send me an email at
evan@figma.com if you're interested.

~~~
networked
I really liked your demo and I'd like to see what your WebGL startup will do.
Is [http://figma.com/](http://figma.com/) the right place to sign up to be
notified when it launches?

Edit: You might want to add some more visual feedback (e.g., blanking the
email input field or hiding it) when you enter your email successfully on the
front page of figma.com. I had to launch Firebug to make sure it accepted my
email with a 200 OK because that check mark icon appearing briefly while the
email field's contents stayed the same seemed suspiciously like a silent
request failure.

------
jarrett
Simple OpenGL question: Can the refractions/caustics be computed entirely in
the shaders? Or do you have to do some of the processing in the CPU* and pass
the results back to the shaders? All the shaders I've seen are "local," in the
sense that they only have access to the interpolated vertex data for their
polygon, plus whatever uniforms have been set. It seems to me that things like
caustics would require non-local information. Is that non-local information
passed via a uniform? If so, I wonder what the data format of that uniform is.

* I know that shaders aren't guaranteed to execute on the GPU, depending on the OpenGL implementation. But for simplicity let's just assume they do.

~~~
ajross
The last caustics implementation I looked at (not this one) did the refraction
stuff per-pixel in shaders based on a CPU-computed mesh deformation.

The more general answer to your question is that in fragment shaders, you can
get "non-locality" via texture lookups inside the shader code.

~~~
jarrett
> you can get "non-locality" via texture lookups inside the shader code.

So you define a way to encode arbitrary non-local data as texture data,
correct? That is, you're hacking textures as a store for arbitrary data
instead of the image data that textures were originally designed to store?

~~~
ramidarigaz
Yep, exactly. There are a number of techniques that take advantage of this.
Most notable are bump mapping and normal mapping.

------
xk0der
Amazing! Given this is (at least) two years old:
[http://www.reddit.com/r/gaming/comments/jjqlc/webgl_water_de...](http://www.reddit.com/r/gaming/comments/jjqlc/webgl_water_demo_wicked_raytracing_reflections/)

------
rdtsc
What is the future of WebGL? I have seen cool demos but is this the way
forward. So one has a game to develop or a complicated visualization, is it
worth investing time in learning WebGL or try to use Canvas directly.

~~~
nairteashop
It's a good question. I have an entire bookmark folder of "cool WebGL demos"
collected over the years, but have seen very few full-fledged applications.

One way you could hedge the WebGL vs. Canvas bet is to use something like
THREE.js, where you use THREE's cameras, lighting, etc and then specify
whether it should use WebGL or Canvas for rendering. But then again, you'd be
betting on THREE.js :)

[https://github.com/mrdoob/three.js/](https://github.com/mrdoob/three.js/)

~~~
AshleysBrain
WebGL is not just for 3D: it can be used for 2D games, where it is _way_
faster than ordinary canvas2d, and allows use of shader effects and such.
Major web game engines like Construct 2 [disclaimer: I am developer] use WebGL
rendering with effects, and fall back to canvas2d if WebGL is not supported.
So at least with Construct 2, it's been in commercial production use for a
couple of years already.

------
scott_karana
The title should be updated to reflect that this is from 2011: all the more
impressive!

([http://www.youtube.com/watch?v=R0O_9bp3EKQ](http://www.youtube.com/watch?v=R0O_9bp3EKQ))

~~~
agumonkey
thanks for this link, my gpu-less 2006 laptop had no chance to run the demo by
itself (the video is almost borderline laggy ..)

------
TazeTSchnitzel
Still just as cool years on.

~~~
petercooper
I had to look up the first time this hit HN and it was #1 for the day on HN
919 days ago! :-) Quite a few comments too:
[https://news.ycombinator.com/item?id=2884141](https://news.ycombinator.com/item?id=2884141)

------
jztein
Can anybody explain how this works? And since this is old, what is state-of-
the-art today?

~~~
constexpr
Author here. The water effect is a simple 2D heightfield simulation, which is
explained pretty well at
[http://www.matthiasmueller.info/talks/GDC2008.pdf](http://www.matthiasmueller.info/talks/GDC2008.pdf).
It essentially just moves each vertex toward the average height of its
neighbors, which turns out to propagate waves that look like water ripples.

The caustics are also pretty simple. Basically you take your heightfield mesh
that represents the water surface and project each vertex independently along
the ray refracted from the light through that vertex (using the vertex normal)
and onto the pool floor. So you now have a mesh that is completely on the pool
floor and contains lots of tiny triangles. To render caustics, just make
triangles that got smaller brighter and ones that got bigger dimmer. I think I
used the ratio of the projected area to the original resting area.

The reflection and refraction raytracing is all hard-coded for the geometry in
the scene, which makes it really easy. It's just a simple sphere and box
intersection test. The "ambient occlusion" is done by making parts of the
objects darker when they get near each other.

State of the art for real-time water uses a full 3D volumetric representation
for the water like in this paper:
[http://www.matthiasmueller.info/publications/tallcells.pdf](http://www.matthiasmueller.info/publications/tallcells.pdf).
This lets you get waves that can fold over themselves like real waves. I
haven't seen any other realtime methods that have caustics as good as the ones
in my demo though.

~~~
Florin_Andrei
> _It essentially just moves each vertex toward the average height of its
> neighbors, which turns out to propagate waves that look like water ripples._

If you look at the equations that govern the liquid surface, the assumptions
that this model is based on are not that bad. Reality is a bit more complex,
but the average-of-neighbors seems like a good start. Pretty simple too, which
is always good computationally.

> _The reflection and refraction raytracing is all hard-coded for the geometry
> in the scene, which makes it really easy._

Which reminds me...

Back in the days of 386 CPUs, I did a real-time 3D ray-tracer that drew a few
spheres rotating around each other, with a fixed light source, and correct
illumination depending on incidence angle at any point on the spheres. All on
a 30 MHz 386 CPU, nothing pre-rendered, no assembly code, no GPU, running at
high frame rate. Bricks where shat when people saw it.

The reality was that the math was highly optimized for that specific scene. I
massaged the equations until I worked out of them all the expensive functions.
No sin() or cos(). I think the worst thing I had was a sqrt(), and even that
was used sparingly.

> _The "ambient occlusion" is done by making parts of the objects darker when
> they get near each other._

You're basically modelling Le Sage's theory of gravitation, with surface
illumination representing "pressure" from the "corpuscles".

[http://en.wikipedia.org/wiki/Le_Sage%27s_theory_of_gravitati...](http://en.wikipedia.org/wiki/Le_Sage%27s_theory_of_gravitation)

------
yzmtf2008
This is really cool, I didn't expect it to be running smoothly (at least not
laggy) on the embedded graphic card of i7 640M ;P

~~~
higherpurpose
It ran fine on my Intel HD 3000, which I think is ~3x slower than your card.

~~~
thrill
My aging Samsung Series 9 has that also, and it worked remarkably well on it.

------
ntaso
This is incredible. Only nitpick: If you dump the ball slowly, it gets a weird
water spike on top of it and the water surface looks like some gel, not like
water. If you pull it out, the ball should be wet. That'd be awesome :D

~~~
j79
In addition to the water spike, I think the lack of a "splash" when the water
hits the surface makes it feel off. I wonder how feasible it is to get this
part of the fluid mechanics right, without the whole thing just crashing and
burning or all janked up...

------
dubcanada
Some of the interfacing with the sphere is a little off, like if you drag it
in and out of the water rapidly it does nothing. And if you slowly drag it
out, the water clings to it a little too long.

But besides that it is very nice.

------
109876
Should this work on mobile? I'm not having any luck on my iPhone 5.

~~~
yzmtf2008
WebGL is not supported by any mobile browser yet
([http://caniuse.com/webgl](http://caniuse.com/webgl)) (edit: it seems that
Blackberry Browser and Opera Mobile support WebGL. My bad, but it is not
possible to use these browsers on iOS)

~~~
pcwalton
Firefox for Android and Chrome for Android support it, according to that table
(unless your driver is blacklisted).

~~~
SnowProblem
Rumors are IE on Windows Phone 8.1 will too. [1]

[1] [http://www.zdnet.com/windows-phone-8-1-the-latest-on-
whats-o...](http://www.zdnet.com/windows-phone-8-1-the-latest-on-whats-on-the-
leaked-feature-list-7000026208/)

------
72deluxe
OpenGL shaders are wonderful. The compute shaders in OpenGL 4.3 (?) onwards
look to be useful; not sure what for, but useful nonetheless!

Let's all bully Apple into supporting something over OpenGL 4.1.

~~~
TazeTSchnitzel
Don't need 3.3 necessarily, if they implement it as an extension.

------
danteembermage
I tried to dig into the source to see, but can anyone tell what algorithm they
are using to propagate the ripples? Normally this would be a Finite Difference
Time Domain [http://en.wikipedia.org/wiki/Finite-difference_time-
domain_m...](http://en.wikipedia.org/wiki/Finite-difference_time-
domain_method) but I'm wondering if they didn't just use growing circles and a
sine wave.

------
jebblue
Very nice, I don't have the talent to do stuff like this, really amazing to
see incredible 3D work and fun being done in the browser.

------
elwell
This is what HN is for! Not articles about Steve Jobs threatening Palm execs.
Also, don't forget to press 'g'.

------
jheriko
seen a lot of these, but this is actually interesting for a change... not just
a copy of something we did 15 years ago on ancient hardware.

the simulation using renderbuffers and float textures is cool - although the
method used is ancient unexciting technology (see the water effect in winamp
avs which uses the same trick in software 15 years ago) it makes sense from
the webdev perspective of 'javascript is damned slow' \- infact probably far
too slow to do even attempt to do this CPU side.

the caustics are much more interesting though - firstly because i didn't know
the trick already or re-invent it during my career or even know about the
OpenGL ES extension that makes it practical (which is very very old on Desktop
and very generally useful).

its always cool to see some raytracing logic applied with some cleverness
applied to get some more mileage out of it at real time...

------
JonnieCache
You can pull the sphere up out of the water and make big waves. Fun stuff.

------
wildpeaks
Is it the same version as the one from 2011 or was it updated recently ?
Because it's a [very cool but] old demo, yet it's popping up in every feed in
the past days.

------
Jeremy1026
The level of awesome is through the roof on this one. Well done.

------
nobodysfool
And now it's offline, looks like we used up all his money.

------
trekky1700
It's amazing the performance difference with WebGL on Chrome vs Firefox. It
lagged to like 5-10 fps with Chrome, but am getting 60+ it seems with Firefox.

~~~
MWil
what's an easy way to show fps in Firefox?

------
namelezz
This should be called "WebGL Water Surface" moving the ball under the water or
hitting the ball against the wall has no affects on the water.

------
k-mcgrady
Not working for me in Safari 7.0.1 - just says loading.

Edit: Tips below on enabling WebGL fixed it.

~~~
double051
Apple still doesn't have WebGL turned on by default in Safari. You can turn it
on by showing the 'Develop' menu (Preferences -> Advanced -> Show Develop
menu), and checking the 'Enable WebGL' option inside.

Should start working after a refresh.

------
davexunit
Really cool!

Is there a better place to store GLSL shaders than in string literals?

~~~
pheelicks
I load them in as separate files. See here for details:
[http://www.pheelicks.com/2014/02/working-better-with-glsl-
so...](http://www.pheelicks.com/2014/02/working-better-with-glsl-source-
files/)

------
axilmar
It's so nice you immediately want to go pool diving.

------
aceperry
This is just _awesome_.

------
designium
That's amazing!

------
mnml_
Old but still cool

------
Yuioup
Oldie but goodie.

------
nichochar
So awesome

