Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit/AppGameKit Studio Showcase / Volumetric Rendering - Simple Example...

Author
Message
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 12th Sep 2022 00:52 Edited at: 12th Sep 2022 00:57
Learning about and experimenting with volumetric rendering has been a fun and challenging exercise for me. I have understood the concepts and techniques, but getting something down in code has been a long time (slow, lol) effort in my spare time between projects and updates. Anyway, I'm to the point now where I'm working with a few different shader ideas to render volumetric clouds (nothing yet that's ready for an example, but I hope to find the time to work on it more and likely share some more advanced code later on). This early attempt below helps illustrate the concept as well as provide a rough template for implementing such an effect through shaders. It seems like a few other AGK/S users were also interested in such a graphics technique, so I thought I'd pass this along. I think something like this would have been helpful to me when I was first trying to work out how to come up with such an effect, so it may prove useful to others.

For a little background, to render something more as a 'volume' and less as a surface involves a technique known as ray-marching. You cast rays from one position to another and then any time the ray intercepts a point within a volume, it gets rendered. Multiple contact points can be rendered across the ray to build up a thickness/alpha, which is good for effects like fog, smoke, and clouds. What's cool about it is that as the ray is aligned with the camera, that volumetric structure appears 3D even though it may just be rendered inside a cube, sphere, or other mesh.

What this sample program does is render a collection of volumetric spheres inside a cube. It's very simple and just illustrates the concept. In the shader, you can see how the rays are marched along the 'inside' of the cube and each time the ray is within the distance of a sphere point, the color yellow is applied. WASD is available to move the camera around, so if you use A and D to move left/right, you'll see that the spheres are rendered at different 3D points volumetrically inside the host cube that has the shader applied. Since everything is rendered on the back face side of the cube, you can fly 'into' the volumetric space with the dots around you.

The 3D points for the spheres are set up in an array on the shader side of things (the sampleDots array in the frag shader). There are 16 of them and you can change the values in the shader to move the 'dots' around in the volumetric space. They are then scaled to account for the size of the volume cube space as set in CloudSizeX, CloudSizeY, and CloudSizeZ. You can see how they are placed inside the volumetric space of the cube and even get cropped (half/partial spheres) when they exceed the bounds of the cube space.

Since we don't have 3D textures in AGK/S, we need to generate our volumetric data on the fly mathematically. But we'd want to do that anyway if we want dynamically changing clouds or smoke. So a variety of noise patterns can be used to generate the 3D data on the shader side of things. This example just establishes a few pre-defined points in an array, but the concept for other patterns is the same.

Attachments

Login to view attachments
fubarpk
Retired Moderator
19
Years of Service
User Offline
Joined: 11th Jan 2005
Playing: AGK is my friend
Posted: 12th Sep 2022 01:07
Looks good sfsw. am I understanding correctly its like 3d layers that you are rendering as 2d?. (glsl)
PK
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 12th Sep 2022 01:13
Yeah, kind of if you think of layers as the steps in the rays. And from the camera's perspective, the spheres are fully 3D inside the volume of the cube. If you move in close to any of the spheres, you can see distortions appear due to the low detail step rate. You can of course include more steps at the cost of a greater performance hit.
Virtual Nomad
Moderator
18
Years of Service
User Offline
Joined: 14th Dec 2005
Location: SF Bay Area, USA
Posted: 17th Sep 2022 05:23
i wont pretend to know anything about shaders but i can't say i've seen such a dramatic drop in FPS for me going from ~550 unhinged on my meager laptop to ~15-30 when i move into the "fog".

when implementing later on, is there a notion of keeping the "fog" at a distance or some scaling to account for being in it?

otherwise, again, i dont know what's really going on but i'm sure it's a nice start
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 17th Sep 2022 07:39
It can be lod balanced to an extent, but that is an odd behavior nonetheless. Volumetric rendering is a task heavy operation overall, although I'd generally expect slowdowns to involve more steps and higher detail. A lot will likely depend on the GPU you are running.
janbo
16
Years of Service
User Offline
Joined: 10th Nov 2008
Location: Germany
Posted: 21st Sep 2022 17:10 Edited at: 21st Sep 2022 18:49
Do you want an simple noise glsl function to play with more cloud like stuff ?


So you ventured into ray-marching... then you'll soon learn about SDF (Signed Distance Field) Functions and how some people create entire worlds from them all shaded and butifull.
SDF's are also good for fonts and to interpolate between stuff in a fancy way.
I tried to use them(SDF's) to interpolate between boundingboxes of IBL(Image Based Lighting) probes. <-too many buzz words... I just wanted to say SDF's are great

lets see if we can shade your balls..i mean spheres... and maybe pass an array of positions instead of hard coding them into the shader.

[Edit]
So i made some changes and wanted to explain what i did:
The first thing i changed was the the hardcoded dot array in the glsl shader whe can do that in AppGameKit and pass the psoitions to the shader using this:

And here is the GLSL code:

And we also dont need to write out the calculations for every dimansion:

As you can see above instead of the distance function i created an SphereSDF function just passing all information and just using the length function instead:

With this you should already have the dots in World space coordinates.
Now i want to have a seperate function where i can add all the different sdf functions to create different objects:

Here i use the min function to find the distance to the closest object.
You can add other shapes and objects in this function too just return the closest distance from of the objects
Now if you go near a sphere you'll see some artifacts sometimes it looks kinda like the moire effect sometimes like layers.
This is because till now we take static steps towards the view direction but we can do it a bit smarter and take smaller steps the closer we are to an object thus resulting in a more detailed scene.
Good thing we already get the closest distance from all objects using our WorldSDF() function and just put it instead of the STEP variable:

Now this if you have a big scene you might have to take many steps sometimes too many steps.
So create an early exit just to be sure not to take too much time:


Final Result:
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 21st Sep 2022 21:59
janbo wrote: "Do you want an simple noise glsl function to play with more cloud like stuff ?"


I do have some cloud generating shader code I've been working with, but I'm always interested in learning and exploring more.

Your approach to generating and exporting the values over is certainly handier and more open to adjustment than hard coding into the shader. Some of what I've been experimenting with for clouds involves generating cloud patterns shader-side (seamless cloud patterns fading to invisible/0 alpha at the cube's edges, perlin/fractal-ish in the middle), so this was just a way to set some fixed points with the same approach.

Ultimately, it would be best to have some seed/parameter values that could be applied on the AGK/S side of things exported to the shader where the pattern is then generated. That way, heavier/thicker clouds could be generated or more thin/patchy cloud patterns. I still have a long way to go before that kind of is ready though
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 25th Sep 2022 00:32 Edited at: 25th Sep 2022 00:33
For example, here are a few small screenshots of where I'm at currently. Since I'm working with planets, I'm wrapping the volumetric projection around a sphere for a cloud surface that follows the shape of planets (rather than a cube structure typically used for flat plane environments). But otherwise, it's the same principles and techniques. There are still some consistency and appearance issues, but it can be viewed inside or outside the cloud 'sphere' layer. No lighting or scattering is taken into account yet, just raw volumetric generation around a sphere.

janbo
16
Years of Service
User Offline
Joined: 10th Nov 2008
Location: Germany
Posted: 26th Sep 2022 16:22
Looks good.
You can also use THE Quad object to render the Volumetric objects on/in and create the sphere "virtually" in the shader.
But im actually not sure about the pros and cons for that method: maybe you have just less objects that way ^^
Also do i see some corners ? is this made with a noise function inside the shader or are you passing a atlass texture to the shader for it ?
Keep it up I'll watch this thread.
SFSW
22
Years of Service
User Offline
Joined: 9th Oct 2002
Location:
Posted: 27th Sep 2022 00:27
I would try the quad approach, just to see how it works and looks, but I've already used that approach for some other full screen effects and I don't think a volumetric shader would play too nicely with other things going on. But I agree, that is certainly a viable approach and could be a good fit for certain applications.

The sphere method I'm using does use one more object index, but it's pretty minimal in terms of any additional overhead and gives me handy control over some placement and sorting around a central planet structure and related terrain (without having to run any depth passes for now anyway).

Yes, there is a hard surface edge at the 'top' of the sphere, which provides a sharp end point at maximum elevation. I haven't yet tapered the tops of the clouds like I have the sides and bottoms yet. Still a lot left to do.

This is done entirely in shader code, no atlas or secondary textures (only the planet sphere inside has a texture). All mathematical calculations in the shader itself with directional animation and changing shapes.

Login to post a reply

Server time is: 2024-11-23 09:26:46
Your offset time is: 2024-11-23 09:26:46