
WebGL + Rust: Basic Water Tutorial - chinedufn
http://chinedufn.com/3d-webgl-basic-water-tutorial/
======
spullara
It doesn't look like water to me. This looks a lot more like water:
[http://madebyevan.com/webgl-water/](http://madebyevan.com/webgl-water/)

~~~
milancurcic
Because it's not solving for the water surface elevation and velocity, only
for light reflection and refraction from a pre-set surface.

> The way that the water appear to move comes from slightly altering the point
> on the refraction and reflection textures that we sample from every frame. >
> > These slight offsets comes from sampling a du/dv map, which is just a
> texture that encodes different x and y offsets.

The app in the link you posted does indeed look like it's solving at least a
shallow water system of equations, and looks very excited to me as a wave
physicist.

~~~
nomel
Completely off topic, but this is a very exciting opportunity for me. What do
you do as a "wave physicist"?

~~~
milancurcic
I study the role of waves in the larger meteorological and oceanographic
context, specifically (1) how they govern momentum and energy exchange between
wind and ocean currents, and (2) how they contribute to Lagrangian surface
transport of pollutants, think oil spills or microplastics.

You can skim through my papers at
[https://milancurcic.com/publications](https://milancurcic.com/publications).
There is also a nice short video where my boss describes what we do in the
lab:
[https://www.youtube.com/watch?v=B6c20IqR2mw](https://www.youtube.com/watch?v=B6c20IqR2mw)

------
shepmaster
For more work from the same author, see their presentation "Percy: Isomorphic
Web Apps with Rust + WebAssembly" at the most recent Rust Belt Rust:

\-
[https://www.youtube.com/watch?v=M6RLvGqQU10&list=PLgC1L0fKd7...](https://www.youtube.com/watch?v=M6RLvGqQU10&list=PLgC1L0fKd7UlpVTHVfLYVtudVx8CzbSxW&index=11)

------
ProjectBarks
I have always thought about getting into rust but since so many of projects
are web focused its hard to integrate it into a project. This really makes me
want to explore Rust!

------
ridiculous_fish
Question about code like this:

    
    
        fn render_reflection_fbo(
            &mut self,
            gl: &WebGlRenderingContext,
            state: &State,
            assets: &Assets,
        ) {
            gl.bind_framebuffer(...);
            gl.viewport(...);
    
            gl.clear_color(...);
            gl.clear(...);
    
    

Setting the viewport and clear color sure look to be mutating, but they are
being called on a shared reference (&WebGlRenderingContext).

Why is it designed this way? Is this design considered sound, or is it a hack?

~~~
chinedufn
Glad you asked!

There's a recent issue [1] in the wasm-bindgen repo that explains this, but
essentially:

\- In this demo the WebGLRenderingContext was created on the Rust side
(technically by calling a light JS shim), but it could've just as well have
been passed in from JS.

\- This means that JS could very easily have had access to the
WebGLRenderingContext.

\- This means that we cannot guarantee that it is immutable. Who is to say
that there isn't a line of JS `gl.mutated! = true;` that we don't know about?
We have no guarantees that whoever instantiated this WebAssembly module isn't
doing something funky.

\- So we treat most DOM / JS APIs as if they have interior mutability, so more
or less you can think of them as `RefCell`'s [2]

\---

As an aside. When you work with WebGL you're just making calls to the GPU and
your state on the GPU gets mutated. The object just controls state
(WebGlRenderingContext) does not get mutated (aside from maybe a couple things
that I'm forgetting..?).

As in.. `gl.viewport` doesn't actually mutate `gl`. But again.. just a small
aside!

In general the idea here is that we can't guarantee that there is only one
mutable reference so there is no point in calling these things `&mut`, even
for things that really do mutate.

\---

So yup! Interior mutability without runtime checks for many of the APIs is
"the right way" in today's idiomatic Rust + WASM + DOM access since you can't
guarantee that there isn't foul play going on from whoever instantiated the
module.

\---

Does this cause issues? It hasn't (noticeably) for me yet but I'm only a
couple months into using `web_sys` so I haven't worked with every single DOM
API.. so grain of salt!

[1] - [https://github.com/rustwasm/wasm-
bindgen/issues/1061](https://github.com/rustwasm/wasm-bindgen/issues/1061)

[2] - [https://doc.rust-
lang.org/std/cell/struct.RefCell.html](https://doc.rust-
lang.org/std/cell/struct.RefCell.html)

------
bencollier49
I like the visual pun with the crow made of stone flying across the scene.

------
CyberDildonics
I'm not sure why rust and webassembly are significant here. All the webgl
commands still need to be javascript and the shaders still need to be glsl.
Almost nothing in a demo like this needs to be done on the cpu.

~~~
chinedufn
Ah interesting - so my thinking on this is:

\- I see that I poorly communicated this in the title, but I was actually
shooting less for "Rust/WASM makes this better!!" and more for "Hey, this is
possible with pretty much just Rust/WASM!" I ended up hand writing about 10
lines of JS [1] in total

\- More minor point - WebGL commands don't need to be called via JS [2] after
anyref and host bindings land, and I think that it's important for people to
know that it's possible to do things on the web without JS (whether that's a
good idea is very situational)!

So yeah apologies if the title could be a bit better - but the main goal was
to share with others that it's possible to build 3d experiences on the web
with Rust today!

And - just to not come off wrong here - I'm not saying whether this is right
or wrong and when to go this route. I am just interested in demonstrating how
to do it :)

But all in all you're right - all of this same experience could totally be
built with only JS if someone so desired!

[1] - [https://github.com/chinedufn/webgl-water-
tutorial/blob/maste...](https://github.com/chinedufn/webgl-water-
tutorial/blob/master/index.html)

[2] - [https://github.com/WebAssembly/reference-
types/blob/master/p...](https://github.com/WebAssembly/reference-
types/blob/master/proposals/reference-types/Overview.md)

