Water ambient occlusion representation in live time

I offer an attempt to generalise caustics computation in real-time using WebGL and ThreeJS in this post. It is crucial to note that this is an attempt; finding a solution that works effectively in all circumstances and runs at 60fps is tough, if not impossible. However, as you can see, we can achieve quite good outcomes with this strategy.
What exactly is caustics?

Caustics are light patterns formed when light is refracted and reflected from a surface, in this example an air/water interface.

Water operates as a dynamic magnifying glass, creating those light patterns due to reflection and refraction on water waves.

This page focuses on caustics as a result of light refraction, specifically what happens underwater.

We need to compute them on the graphics card (GPU) to reach steady 60fps, thus we'll do it fully with shaders written in GLSL.

To compute them, we must:

Determine the refracted rays at the water's surface (which is straightforward in GLSL as a built-in function is provided for that)

Using an intersection method, determine where those rays intersect the environment.

Calculate the caustics intensity by looking at where the rays are converging.

Information Transformation Services is endowing the clients with a stunning and impressive visual experience crafted by 3D Modeling Services . We are completely forted to offers our customers with a range of appealing 3D designs that are carefully crafted to meet with all type of requirements.

The well-known WebGL-water demonstration

Evan Wallace's demo of visually believable water caustics using WebGL has always fascinated me: madebyevan.com/webgl-water

I highly recommend reading his Medium essay on how to compute them in real-time using a light front mesh and partial derivative GLSL algorithms. His implementation is lightning quick and really attractive, but it has a few limitations: it only works with a cubic pool and a sphere ball in the pool. You can't place a shark underwater and expect the demo to function since the shaders are hard-coded to think it's a sphere ball underwater.

The reason for submerging a sphere is that determining the intersection of a refracted light ray and a sphere was simple and included extremely simple math.

All of this is good for a demonstration, but I wanted a more generic solution for caustics computation, so that any type of unstructured mesh might lay in the pool like a shark.

Let us now move on to our strategy. In this post, I'll assume you're already familiar with the fundamentals of 3D rendering via rasterization, as well as how the vertex shader and fragment shader collaborate to draw primitives (triangles) on the screen.

Working with GLSL constraints

Shaders developed in GLSL (OpenGL Shading Language) can only access a limited amount of scene information, such as:

Characteristics of the vertex you're presently drawing (position: 3D vector, normal: 3D vector, etc.). You can send your own properties to the GPU, but they must be of a GLSL built-in type.

At the current frame, uniforms that are constant for the entire mesh you are drawing. It could be a texture, the camera projection matrix, a light direction, or something else. It must have the following built-in types: int, float, sampler2D for textures, vec2, vec3, vec4, mat3, mat4.

However, there is no way to access meshes that are present in the scene.

This is why the webgl-water example could only be created with a minimal 3D scene. It was simpler to compute the intersection of the refracted ray and a very simple shape represented by uniforms. In the case of a sphere, it may be described by a position (3D vector) and a radius (float), and this information can be supplied to the shaders via uniforms, and the intersection calculation includes fairly simple math that can be executed easily and rapidly in a shader.

My articles is a writer’s community that provides you a guest posting service for your website no matter which niche does your website belongs from.
You are warmly welcome to signup and share your stories to all over the world. Follow your favorite writers, create groups, forums, chat, and much much more!

Some ray-tracing techniques used in shaders transfer meshes across textures, but this is not feasible for real-time WebGL rendering in 2020. We must keep in mind that we need to compute 60 images per second while using a sufficient number of rays to achieve a satisfactory output. If we compute the caustics using 256x256=65536 rays, we must perform a significant number of intersection calculations per second (which also depends on the number of meshes in the scene).

We need to figure out how to represent the sub-water environment as uniforms and compute the intersection while yet maintaining good performance.