I thought I’d ask the brains trust about this challenging proposition - maybe @PatrickRyan or someone else in the community has some good ideas?
I’m wanting to create realistic surf and gentle waves crashing on a small stretch of beach, with wave crests, edge foam at the shoreline and around protruding rocks, receding wet sand as waves recede, refraction and reflections. It doesn’t need to be continuously random and unique - it could just be a looping vertex animation with some additional shaders. It does need to be quite performant i.e. I can’t expend all my cycles simulating just the water, as it’s not the focus of the project.
As far as Babylon goes, I’m aware of the water material and ocean demo and a cartoon edge foam water shader someone is using for a game, but nothing quite like this.
I also some found some 7 year old CG Geek Blender tutorial videos:
@inteja apologies, may i quickly ask at the start of this if any measure of shaders are known to be performant on lowcapability devices? [best i figure an approximation for lowcaps is (gfx.engine.getCaps().maxRenderTextureSize <= 4096)] There seems to be a coastal shelf on performance using shaders on such devices.
@withADoveInOneHand sorry I don’t have a specific answer for you. All materials are shaders, and standard or PBR materials work even on low end devices, so it depends on the scene, geometry, amount of work the shaders are required to do etc. There’s no simple answer.
All I was getting at I guess is that the ocean demo for instance is very realistic, but it’s also doing a lot of simulation work to achieve that result, and therefore not really suited to this use case, apart from the fact it doesn’t simulate waves crashing on a beach.
If I could get away with a looping vertex animation exported from Blender plus a few simple shaders applied, that’d be ideal, rather than a heavy simulation.
Sort of like this Castaway - Shadertoy but more waves/surf … and far less intensive to run, which is why I’m thinking that exporting a looped vertex animation from Blender with a simpler water and edge foam shader applied in Babylon might be the best compromise of performance and visual quality.
Sorry, maybe I’m not clear. It’s a content creation question, not how to import models in Babylon. It’s just a tricky type of 3D content to create. Here’s what I’m envisioning (created with ChatGPT) - an animated version of this:
@inteja, this is an interesting problem if you want to balance looking good and being cheap. The biggest challenges I see are this:
If you want displacement on the foam, you will need more resolution at the front of your wave than the back to handle the increased noise in the displacement at the front. At the same time, you can see in your example, the lead edge of the water has more churn in the middle of the image than toward the ends, so we also may need to be able to change the spacing between the edges at the front of the wave.
There is a doubling of the water effect from the receeding foam of the previous wave that will need isolated animation and mesh as it washes back out before being pushed by the next wave. The foam streaks on this one will need to move om a way that suggests an organic path of water running away from the sand
The shape of the wet sand needs to mirror the last wave that hit the shore. This suggests we need to use a texture for the pattern of the wave each cycle so that we can apply the same texture to the displacement of the wave mesh and the interpolation between the base color and roughness values of the sand.
The one trick that came to mind initially was to use a particle system to simulate the foam emitting from the mesh vertices at the front of the wave to save on some vertex displacement, but I think the patterns created by the foam would be hard to control in particles. We have a new feature for support of flow maps on particle systems, but right now it is only in screen space and while we are working on world space flow maps, they will be volumetric, so unable to follow a mesh surface.
So this brings me back to thinking about this from a texture blend solution. The shape of the wave displacement up the sand controlled by one texture and the displacement of the height of the foam controlled by a second. And a third specifying the distance the foam covers on the lead edge of the wave. Though you could shape the front edge of the wave mesh with stacked sin/cos noise to create an irregular curve, matching that to texture would be tricky.
I can see using multiple gradient noises channel packed into a single texture with UV offsets animating creating the pattern you use for displacement on the wave front as well as being passed to the other shaders for the receding foam mesh and the wet sand mesh. Since you would be changing UVs to create the wave shape, you can simply pass the same noise texture to all three and then simply pass a series of floats to each shader to create the same curve shape in each.
The water that is without foam would have some vertex displacement with lower resolution than the foam edge with the higher frequency waves being done in the normal. This can simply be a couple of noise textures for water waves animating UVs in opposite directions to create the wave noise. This would help for the reflections on the surface. For the refraction, I would likely not do real refraction mostly because of cost. I think you could simulate it by interpolating between the base color for sand and water based on vertex position. Also adding a noise texture to shift the interpolation value would also simulate that refraction of the color of the water based on depth without doing any render textures for refraction.
Displacement around things in the water like these rocks needs some extra consideration along the lines of flow maps to get the texture and displacement to wrap around these objects.
As you say, there are a ton of solves here that could be applicable. I don’t have time right now to jump into making an example, but if you aren’t in a rush, I may be able to pivot to a quick example next week if I can find a window in the schedule. Otherwise, please ping with questions and we can dig deeper into strategy and options.
Awesome insights (as usual) @PatrickRyan! You never disappoint.
I’ll need to go over it a few times for it to sink in.
I’m in no rush, so if you have some time and inclination to work on an example at some point, I’d be eternally grateful. But in the meantime, you’ve given me more than enough to get started trying a few things out.