Sunday, June 25, 2017

Martian sandstorm

Now a fully interactive volumetric sand storm, probably somewhere on Mars.
This marks an intermediate milestone following months of research into volume rendering. It uses finite differences solver for a fluid dynamics equation, some additional research into graphics pipeline on a Mac and iOS.
Note the shadows, they depend on volume density, and also note the unbounded nature of volumes. Other methods would produce visible banding artifacts.


Saturday, June 17, 2017

Unexpected volumetric clouds

I was playing with code that I am testing to produce fluid dynamic effects, and I came across a weird cloud generating setup.
The advection part is failing at some point here and causes gas density to freeze in some regions of the map. It remains static and appears as a cloud, and I think this can be further improved to produce realistic looking real cloud. What's missing is a better phase function, and shading based on anisotropic scattering of different wavelenths.




Monday, May 29, 2017

Fun with self-shadowing volumetrics

As a preparation to a full-fledged interactive volume rendering, here is the first functional volumetric composition. It uses a few techniques to achieve a self-shadowing appearance, as you would expect from a real-life volume of transparent matter.


Wednesday, May 24, 2017

Volumetric hints.

A few volume rendering hints.

1. Cannot discard writing into render-targets selectively in an MRT frame-buffer. This arises, for example, when two targets are used to store two custom denormalized depth buffers. A frame-buffer has a depth attachment as well, but it is used in a regular sense of a depth buffer.

2. Volume rendering can use analytic volume buffer or a set of depth textures. To limit volume to a custom 3D shape requires preliminary step to render that shape into two depth attachments, one with inverted normals and inverted depth test:
// Enable depth test, inverted, front to back.
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);

// Render only back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

// Clear the buffers.
// Note that the most distant shape will overwrite all others.
glClearDepth(0.0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//... Render the shape of the volume, i.e. a cloud.

// Enable depth test, back to front.
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

// Render only front faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

// Clear the buffers.
glClearDepth(1.0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//... Render the same shape of the volume.


3. In a fragment shader calculate the distance to a rasterized point. Do it in fragment instead of in a vertex, hoping for speedup due to hardware interpolation. If two vertices spread out evenly in a view space, their depths will be equal and much bigger than the distance to a front clipping plane. This results in artifacts when moving towards a volume and crossing it.

4. A depth buffer attachment can now be shared between with other frame-buffers. It works for simple convex shapes as volumes that can be rendered from inside and outside. The real work is to be done elsewhere to modulate this shape with other detail, i.e. noise.

Saturday, May 13, 2017

Volumetric rendering with custom volume shapes


It took me a week to figure out a problem with a vertex shader not able to interpolate a single float output.
I started with a multi-pass stage that produced a volume from a shape, then fed that volume to a volumetric pass and observed unexplainable artefacts. When flying through a scene and entering a volume the buffer that was clipped by a view frustum's near plane would mangle a default buffer value (set by glClear). Attempts to fix that by playing with glEnable(GL_DEPTH_CLAMP), glDepthRange(-1.0, 1.0) etc did not help.
What did work was switching from a float output to a whole vec3, and calculating depth in a fragment shader. Inefficient, and annoying.

Friday, April 14, 2017

Real-time atmospheric effects

This demonstrates a few atmospheric effects that I've added to a custom engine. It is real-time, using stages in shader pipeline, and very customizable (fog, lighting, composition etc).
In addition, the demo is showing Fourier transform to simulate ocean waves.
More to follow.